Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android를 여행하는 히치하이커를 위한 안내...

Android를 여행하는 히치하이커를 위한 안내서_ML Vision편

비 안드로이드 개발자도 ML Vision 모델을 안드로이드 단말에서 테스트 해볼 수 있도록,
간단한 가이드를 작성했습니다.
https://github.com/fornewid/tensorflow-style-transfer-android

Sungyong An

July 30, 2019
Tweet

More Decks by Sungyong An

Other Decks in Programming

Transcript

  1. <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE"/> override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) ... if (allPermissionsGranted(context)) { startCamera() } else { requestPermissions( REQUIRED_PERMISSIONS, ൤஖ೞ੉ழ੄ അप
  2. private fun allPermissionsGranted(context: Context): Boolean { return REQUIRED_PERMISSIONS.all { ContextCompat.checkSelfPermission(context,

    it) == PackageManager.PERMISSION_GRANTED } } companion object { private const val REQUEST_CODE_PERMISSIONS = 77777 private val REQUIRED_PERMISSIONS = arrayOf( Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE ) } ൤஖ೞ੉ழ੄ അप
  3. 1. ࢸ஖ػ জ ই੉௑ Long Click 2. 'জ ੿ࠁ' Click

    3. 'ӂೠ' Click 4. '੷੢ҕр', '஠ݫۄ' ӂೠਸ ೲਊ 5. জ ੤प೯ ⚠ Sample Project݅ ࢎਊೡ Ѫ! Allow in AppSetting
  4. Take a photo A N D R O I D

    H I T C H H I K E R
  5. #1. from Camera Camera1 API (API 1 ੉࢚) Camera2 API

    (API 21 ੉࢚) CameraX API (API 21 ੉࢚, alpha)
  6. • app/build.gradle Use CameraView F R O M C A

    M E R A implementation 'com.otaliastudios:cameraview:2.0.0-rc2' Link: https://github.com/natario1/CameraView
  7. • app/AndroidManifest.xml Use CameraView F R O M C A

    M E R A <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
  8. • app/res/layout/*.xml Use CameraView F R O M C A

    M E R A <com.otaliastudios.cameraview.CameraView android:id="@+id/cameraView" android:layout_width="match_parent" android:layout_height="match_parent" android:keepScreenOn="true" app:cameraFacing="back|front" app:cameraGestureTap="none|autoFocus|takePicture" app:cameraGesturePinch="none|zoom|exposureCorrection" app:cameraUseDeviceOrientation="false" ... />
  9. • Kotlin - Picture Mode Use CameraView F R O

    M C A M E R A cameraView.addCameraListener(object : CameraListener() { @UiThread override fun onPictureTaken(result: PictureResult) { @WorkerThread result.toBitmap(object : BitmapCallback { @UiThread override fun onBitmapReady(bitmap: Bitmap?) { ... } }) } }) cameraView.takePicture() Bitmap
  10. • Kotlin - Frame Processor Use CameraView F R O

    M C A M E R A cameraView.addFrameProcessor(object : FrameProcessor { @WorkerThread override fun process(frame: Frame) { val data: ByteArray = frame.data val width: Int = frame.size.width val height: Int = frame.size.height val format: Int = frame.format // android.graphics.ImageFormat val rotation: Int = frame.rotation // 0, 90, 180, 270 } }) ByteArray
  11. • Kotlin - Clear Listeners Use CameraView F R O

    M C A M E R A cameraView.removeCameraListener(...) cameraView.removeFrameProcessor(...) // or cameraView.clearCameraListeners() cameraView.clearFrameProcessors()
  12. • Kotlin - Consider lifecycle of Activity Use CameraView F

    R O M C A M E R A class ... : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) cameraView.setLifecycleOwner(this) // Add Listeners } override fun onDestroy() { // Remove Listeners super.onDestroy() } }
  13. • Kotlin - Consider lifecycle of Fragment Use CameraView F

    R O M C A M E R A class ... : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) cameraView.setLifecycleOwner(viewLifecycleOwner) // Add Listeners } override fun onDestroyView() { // Remove Listeners super.onDestroyView() } }
  14. • start/build.gradle Use Common Intent F R O M G

    A L L E R Y galleryButton.setOnClickListener { Gallery.takePicture(activity) } override fun onActivityResult(requestCode: Int, ...) { super.onActivityResult(requestCode, resultCode, data) Gallery.onPictureTaken(requestCode, resultCode, data) { uri -> … } } Link: https://developer.android.com/guide/components/intents-common#Storage
  15. • Kotlin - Pick a image from gallary Use Common

    Intent F R O M G A L L E R Y fun takePicture(activity: Activity) { val intent = Intent(Intent.ACTION_GET_CONTENT) intent.addCategory(Intent.CATEGORY_OPENABLE) intent.type = "image/*" activity.startActivityForResult( Intent.createChooser(intent, "Select Picture"), REQUEST_GET_SINGLE_FILE /* 1234 */ ) }
  16. • Kotlin - Take a image URI Use Common Intent

    F R O M G A L L E R Y fun onPictureTaken( requestCode: Int, resultCode: Int, data: Intent?, callback: (Uri) -> Unit) { if (requestCode == REQUEST_GET_SINGLE_FILE && resultCode == Activity.RESULT_OK) { data?.data?.run(callback) } } URI
  17. • Data Types: • android.graphics.Bitmap • ByteArray (= byte[]) •

    android.net.Uri • android.media.Image • FirebaseVisionImageܳ ੉ਊೞৈ ࣻҊܳ ؏ ࣻ ੓׮. ੉੹ ױ҅ীࢲ оઉৡ ؘ੉ఠܳ Bitmap ഋక۽ ߸ജ೧ঠ ೠ׮. #3. Any to Bitmap
  18. • app/build.gradle Use FirebaseVisionImage A N Y T O B

    I T M A P implementation 'com.google.firebase:firebase-ml-vision:22.0.0' Link: https://firebase.google.com/.../firebase/ml/vision/common/FirebaseVisionImage
  19. • ByteArray to Bitmap Use FirebaseVisionImage A N Y T

    O B I T M A P val bitmap = FirebaseVisionImage.fromByteArray( frame.data, // ByteArray FirebaseVisionImageMetadata.Builder() .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setWidth(frame.size.width) .setHeight(frame.size.height) .setRotation(FirebaseVisionImageMetadata.ROTATION_90) .build()) .bitmap
  20. • Uri to Bitmap Use FirebaseVisionImage A N Y T

    O B I T M A P val bitmap = FirebaseVisionImage .fromFilePath(context, uri) // Context, Uri .bitmap
  21. • Media Image to Bitmap Use FirebaseVisionImage A N Y

    T O B I T M A P val bitmap = FirebaseVisionImage .fromMediaImage( image, // android.media.Image FirebaseVisionImageMetadata.ROTATION_90 ) .bitmap
  22. Save a image A N D R O I D

    H I T C H H I K E R
  23. • app/AndroidManifest.xml Global Screenshot T O E X T E

    R N A L S T O R A G E <uses-permission android:name= "android.permission.WRITE_EXTERNAL_STORAGE" />
  24. Global Screenshot T O E X T E R N

    A L S T O R A G E fun saveBitmap(context: Context, bitmap: Bitmap) { val imageTime = System.currentTimeMillis() val imageDate = SimpleDateFormat("yyyyMMdd-HHmmss").format(Date(imageT val imageFileName = String.format("Stylize_%s.png", imageDate) val imageDir = File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), DIR_NAME) val imageFilePath = File("Stylizes", imageFileName).absolutePath ... Link: http://androidxref.com/9.0.0_r3/xref/.../SystemUI/.../GlobalScreenshot.java
  25. Global Screenshot T O E X T E R N

    A L S T O R A G E ... try { imageDir.mkdirs() val out = FileOutputStream(imageFilePath) bitmap.compress(Bitmap.CompressFormat.PNG, 100, out) out.flush() out.close() } catch (IOException) { ... } } Link: http://androidxref.com/9.0.0_r3/xref/.../SystemUI/.../GlobalScreenshot.java
  26. • জ ࢸ੿ীࢲ ӂೠਸ ࣻزਵ۽ ߸҃ೡ ࣻب ੓णפ׮. • ஠ݫۄо

    ೙ਃೞ׮ݶ natario1/CameraViewܳ ୶ୌ೤פ׮. • ੷੢ػ ੉޷૑ܳ ࠛ۞ৢ ٸח Common Intentܳ ੉ਊ೧ࠁࣁਃ. • FirebaseVisionImageܳ ࢎਊೞৈ Bitmapਵ۽ औѱ ߄Ե ࣻ ੓णפ׮. • ੉޷૑ܳ ੷੢ೡ ٸ, Global Screenshot ௏٘ܳ ଵҊ೧ࠁࣁਃ. Summary Link: https://github.com/fornewid/tensorflow-style-transfer-android
  27. Q & A A N D R O I D

    H I T C H H I K E R