Android/WebRTC/OpenGL/OpenCV Developer
Android/WebRTC/OpenGL/OpenCV Developer(Park Jang Hyeok)
Android, PHP, C++, C#, OpenCV, WebRTC, OpenGl ES, iOS, Node.js 관련 개발을 했었습니다. 현재 카카오헤어샵에서 근무하고 있습니다. 최신 기술을 꼼꼼히 검토하며 적용하려 하며, 적정한 디자인 패턴을 적용하여 유지보수에 효율적인 방법을 찾는 개발자입니다.

아래와 같이 스무디 서비스 내에서 영상 이펙트 기능을 구현하였습니다. 또한 얼굴인식형 스티커 이펙트도 구현하였습니다.

KakaoTalk_Video_20191203_1112_11_896.mp4_000001800.pngKakaoTalk_Video_20191203_1112_17_668.mp4_000002400.png

좋아요 0
    댓글 0
    1. 역활 : 메인 개발자
    2. 내용
      • 카카오헤어샵은 헤어샵 및 네일샵 예약 중개 서비스로, 안드로이드 파트를 담당해서 유지/보수/신기능 개발 등을 진행
    좋아요 0
      댓글 0
      2018년 8월 7일 03시38분 ·  집필활동

      [Android] Google Analytics 쉽게 적용하기

      안드로이드 개발 중 Google Analytics를 사용하게 되었는데, 좀더 쉽고 편리하게 사용하고자 하였다.   그래서 Application 단에서 GoogleAnalytics 관련된 처리를 다루고, 실제 소스상에서 쉽게 다루고자 추상 팩토리 패턴으로 작성하여 보았다.   여기서는 gradle에 dependency 추가와 global-tracker.xml 에 대한 설명의 생략합니다.(구글링하면 금방 나옵니다.)   GoogleAnalyticsFactory.java 해당 클래스 가장 뼈대가 될 클래스이다. GoogleAnalytics의 인스턴스를 할당하고, Tracker를 초기화하고 생성한다.import android.content.Context; import android.support.multidex.MultiDexApplication; import com.google.android.gms.analytics.GoogleAnalytics; import com.google.android.gms.analytics.Tracker; public abstract class GoogleAnalyticsFactory { private Tracker mTracker; /** * Gets the default {@link Tracker} for this {@link MultiDexApplication}. * @return tracker */ synchronized public Tracker getDefaultTracker() { if (mTracker == null) { GoogleAnalytics analytics = GoogleAnalytics.getInstance(mContext); // To enable debug logging use: adb shell setprop log.tag.GAv4 DEBUG mTracker = analytics.newTracker(R.xml.global_tracker); } return mTracker; } protected Context mContext; public GoogleAnalyticsFactory(Context context) { this.mContext = context; } public abstract void sendAnalyticsEvent(String category, String action); public abstract void sendAnalyticsScreen(String screen); }   GoogleAnalyticsImpl.java GoogleAnalyticsFactory 클래스에서 abstract으로 선언한 메서드를 정의한다. import android.content.Context; import android.content.Context; import android.os.Handler; import com.google.android.gms.analytics.GoogleAnalytics; import com.google.android.gms.analytics.HitBuilders; import com.google.android.gms.analytics.Tracker; public class GoogleAnalyticsImpl extends GoogleAnalyticsFactory { private Tracker mTracker; public GoogleAnalyticsImpl(Context context) { super(context); mTracker = getDefaultTracker(); } @Ov...

      http://k9327.tistory.com/1

      좋아요 0
        댓글 0
        2018년 8월 7일 03시38분 ·  집필활동

        [Android] Glide의 SimpleTarget 관련 처리

        Glide 라이브러리 쓰다보면 비동기 처리 쪽은 SimpleTarget 관련해서 문제가 생길 때가 있다.   나같은 경우는 Fragment에서 Glide로 비트맵을 받아서 Rounded처리를 하고 난 뒤 이미지 뷰에 넣는 작업을 작성해놨는데,   Glide가 다 로드가 되지 않는 상태에서 Fragment를 나가게 되면, Null Point Exception을 뿜으면서 죽어버리는 현상을 맞이하게 되었다.   Fragment의 인스턴스는 해제되었지만, SimpleTarget에 있는 큐들은 해제되지 않았기 때문이다.   이와 관련해서 Glide의 RequestManager를 이용하여 처리하여 해결하였다.(삽질과 구글링으로 극복을....)     RequestManager mGlideRequestManager; mGlideRequestManager = Glide.with(this); @Override public void onResume() { super.onResume(); mGlideRequestManager.resumeRequests(); } @Override public void onPause() { super.onPause(); mGlideRequestManager.pauseRequests(); } @Override public void onDestroy() { mGlideRequestManager.onDestroy(); super.onDestroy(); }   출처 : http://gogorchg.tistory.com/entry/Android-Glide-Library-%EC%82%AC%EC%9A%A9%EC%8B%9C-%EC%B0%B8%EA%B3%A0-%EC%82%AC%ED%95%AD...

        http://k9327.tistory.com/2

        좋아요 0
          댓글 0
          2018년 8월 7일 03시38분 ·  집필활동

          [Android] RxJava를 이용한 EventBus

          회사 서비스를 제작하던 중, Broadcast나 interface로 처리하기 곤란한 부분들이 존재하였다.그래서 EventBus를 사용할려고 하였으나, 기존 프로젝트에 RxJava를 이용하고 있었기에 RxJava를 이용하여 EventBus를 만들어 사용하기로 하였다.Rx의 Subscription을 잘 이용하면 될거라고 생각하고 작성하였다.장점은 BroadCast로 전달할 수 없는 객체를 전달할 수 있으며, interface를 여러개 만들어 전달에 전달을 하지 않아도 된다는 점이다. 또한 Lifecycle만 잘 지키면 메모리 관리 측면에서 이득을 볼 수 있는 부분이 있다.RxEventBus.java12345678910111213import rx.Observable;import rx.subjects.PublishSubject;import rx.subjects.SerializedSubject;import rx.subjects.Subject;public class RxEventBus {    private final Subject<Object, Object> bus = new SerializedSubject<>(PublishSubject.create());    public void post(Object o) {        bus.onNext(o);    }    public Observable<Object> getBusObservable() {        return bus;    }}Colored by Color ScriptercsEventBus.java12345678910public class EvnetBus extends RxEventBus {    private static EvnetBus instance;     public static EvnetBus get() {        if (instance == null)            instance = new EvnetBus();        return instance;    } }Colored by Color ScriptercsData.java-> RxEventBus를 통해 전달할 객체이다. 얼마든지 Customize해서 써도 상관없다.123456789101112Data.javapublic class Data {     private String mTag;      public Data(String tag) {          this.mTag = tag;    ...

          http://k9327.tistory.com/3

          좋아요 0
            댓글 0
            2018년 8월 7일 03시38분 ·  집필활동

            [Android] 안드로이드 개발에 유용한 라이브러리 정리

            라이브러리 관련 정리된 Github Pagehttps://github.com/wasabeef/awesome-android-ui안드로이드 Crop 관련 라이브러리https://github.com/ArthurHub/Android-Image-Cropperhttps://github.com/Yalantis/uCropWebView Extend https://github.com/TheFinestArtist/FinestWebView-Android...

            http://k9327.tistory.com/4

            좋아요 0
              댓글 0
              2018년 8월 7일 03시38분 ·  집필활동

              [Android] Retrofit 2.0 Multipart Post 전송

              프로젝트에 Retrofit 2.0을 이용하여 개발하던 중, Multipart로 사진 파일을 서버로 전송해야 하는 상황이 있었다.이 때, 여러 삽질을 통해 Multipart에 대해서 길진 않지만 정리하고자 한다.아래와 같이 EndPoint를 @Multipart 어노테이션을 이용하여 정의한다.(여기까지는 Retrofit Docs를 읽으면 알 수 있다....)1234@Multipart@POST("업로드 서버 주소")Observable<CommonApiResponse> uploadPhoto(        @Part MultipartBody.Part file );cs하지만 @Part에 해당하는 정보가 무엇이 들어가야 하는지에 대한 설명은 어디에도 나와있지 않았다... (고로 나도 설명하지 않으려...농담이다...)MultipartBody.Part 클래스를 이용하여 FormData를 만들 수 있다. (아래처럼)여기서 파일과 같은 정본느 RequestBody를 이용하여 Body를 구성할 수 있다. (한국어인지.... 번역체인지...)123MultipartBody.Part.createFormData("file", file.getPath(), RequestBody.create(MediaType.parse("image/jpeg"), file)); MultipartBody.Part.createFormData("file", Urls.encode(fileName));Colored by Color Scriptercs위의 조합을 잘 이용하면, Multipart Post 전송을 할 수 있다.추가로 Mulipart 인코딩관련 어노테이션 처리를 할 필요가 없다. MultiPartBody나 RequestBody에서 알아서 인코딩을 해준다.Retrofit의 레퍼런스가 정리가 잘되어 있으면 좋겠지만, 정리가 되지 않아 일일히 Retrofit의 JavaDocs를 찾아가며 삽질한 결과 알아낼 수 있었다....ㅠㅠ...

              http://k9327.tistory.com/5

              좋아요 0
                댓글 0
                2018년 8월 7일 03시38분 ·  집필활동

                [Android] Soft Key 기종의 소프트 키보드 관련 문제 해결 방법

                현상 키보드값을 제대로 가져오지 못하여, 이모티콘 레이아웃이 화면은 덮는 현상이 벌어지거나, 너무 아래에 치우쳐져서 나오는 현상이 발생합니다.최하단 이미지 첨부 원인 Android SDK 21 이후부터 Soft key를 사용하는 기종에서 화면을 가져올 때, 소프트키까지 포함한 화면을 가져오면서 화면의 높이까지 원하지 않는 크기로 가져오면 발생하게 되었습니다. 해결책 SDD 21 이후 버전에 대해서 windowManger를 통해서 DefaultDisplay르 가져오도록 요청하게 해야 합니다./** * SDK 21 이후 부터 소프트키 기종 화면 높이를 잘 못 가져오는 현상 있음 */ if(Build.VERSION.SDK_INT >= 21) { Display display = getActivity().getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); screenHeight = size.y; } else { screenHeight = paramParentLayout.getRootView().getHeight(); } 모듈 변경 SoftKeyboard의 크기를 알아내는 뷰를 새로 작성하여 사용함View를 상속 받아 사용하며, View의 onSizeChanged 함수를 활용하여 뷰 변화를 통해 키보드의 높이를 알아낼 수 있다.SoftKeyboardDectectorView.javapackage com.wescan.alo.view; /** * Created by hazuki21 on 16. 3. 10.. */ import android.app.Activity; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; import android.view.Display; import android.view.View; public class SoftKeyboardDectectorView extends View { private Context context; private boolean mShownKeyboard; private OnShownKeyboardListener mOnShownSoftKeyboard; private OnHiddenKeyboardListener onHiddenSoftKeyboard; private int diffHeight; public SoftKeyboardDectectorView(Context context) { this(context, null); this.context = context; } public SoftKeyboardDectectorView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SoftKeyboardDectectorView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Activity activity = (Activity) context; Rect windowRect = new Rect(); activity.ge...

                http://k9327.tistory.com/6

                좋아요 0
                  댓글 0
                  1. 역활 : 메인 개발자 (60%)
                  2. 내용
                    • FineApple이라는 영상 기반 데이팅 서비스를 제작
                  3. 업무
                    • 서비스 기획 참여 (20%)
                    • UI 관련 구현 (40%)
                    • WebRTC 관련 모듈화 및 리팩토링(100%)
                    • API 관련 설계 (30%)
                    • 채팅 및 랜덤매칭관련 기능 설계 (80%)
                  좋아요 0
                    댓글 0
                    1. 역활 : 메인 개발자 (70%)
                    2. 내용
                      • 기존 캔디카메라 서비스에 영상통화 서비스 "캔디콜" 기능을 추가하는 프로젝트
                    3. 업무
                      • 기존 코드 분석
                      • OpenGL 기반 영상처리 모듈 제작 (100%)
                      • 서비스 UI 관련 제작(40%)
                    좋아요 0
                      댓글 0