Slide 1

Slide 1 text

Androidܳ ৈ೯ೞח
 ൤஖ೞ੉ழܳ ਤೠ উղࢲ ML Vision ಞ

Slide 2

Slide 2 text

안성용 Sungyong An Clova AI Production

Slide 3

Slide 3 text

Ҋ޹੄ द੘..

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

൤஖ೞ੉ழ੄ ࢤп & ✨

Slide 6

Slide 6 text

൤஖ೞ੉ழ੄ അप & ✨

Slide 7

Slide 7 text

ઑӘ ؏ Ҋాझۣѱ, ੉޷૑ ࢎਊೞӝ ݾ಴

Slide 8

Slide 8 text

Get device permission A N D R O I D H I T C H H I K E R

Slide 9

Slide 9 text

• app/AndroidManifest.xml ൤஖ೞ੉ழ੄ ࢤп

Slide 10

Slide 10 text

override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) ... if (allPermissionsGranted(context)) { startCamera() } else { requestPermissions( REQUIRED_PERMISSIONS, ൤஖ೞ੉ழ੄ അप

Slide 11

Slide 11 text

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 ) } ൤஖ೞ੉ழ੄ അप

Slide 12

Slide 12 text

о੢ ए਍ ߑߨ..? Search on google: "android permission easily" /

Slide 13

Slide 13 text

1. ࢸ஖ػ জ ই੉௑ Long Click 2. 'জ ੿ࠁ' Click 3. 'ӂೠ' Click 4. '੷੢ҕр', '஠ݫۄ' ӂೠਸ ೲਊ 5. জ ੤प೯ ⚠ Sample Project݅ ࢎਊೡ Ѫ! Allow in AppSetting

Slide 14

Slide 14 text

Take a photo A N D R O I D H I T C H H I K E R

Slide 15

Slide 15 text

#1. from Camera

Slide 16

Slide 16 text

#1. from Camera Camera1 API (API 1 ੉࢚) Camera2 API (API 21 ੉࢚) CameraX API (API 21 ੉࢚, alpha)

Slide 17

Slide 17 text

01010101010101 010101 010101 01010101010101

Slide 18

Slide 18 text

CameraView!

Slide 19

Slide 19 text

• 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

Slide 20

Slide 20 text

• app/AndroidManifest.xml Use CameraView F R O M C A M E R A

Slide 21

Slide 21 text

• app/res/layout/*.xml Use CameraView F R O M C A M E R A

Slide 22

Slide 22 text

• 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

Slide 23

Slide 23 text

• 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

Slide 24

Slide 24 text

• Kotlin - Clear Listeners Use CameraView F R O M C A M E R A cameraView.removeCameraListener(...) cameraView.removeFrameProcessor(...) // or cameraView.clearCameraListeners() cameraView.clearFrameProcessors()

Slide 25

Slide 25 text

• 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() } }

Slide 26

Slide 26 text

• 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() } }

Slide 27

Slide 27 text

#2. from Gallery

Slide 28

Slide 28 text

• 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

Slide 29

Slide 29 text

• 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 */ ) }

Slide 30

Slide 30 text

• 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

Slide 31

Slide 31 text

• Data Types: • android.graphics.Bitmap • ByteArray (= byte[]) • android.net.Uri • android.media.Image • FirebaseVisionImageܳ ੉ਊೞৈ ࣻҊܳ ؏ ࣻ ੓׮. ੉੹ ױ҅ীࢲ оઉৡ ؘ੉ఠܳ Bitmap ഋక۽ ߸ജ೧ঠ ೠ׮. #3. Any to Bitmap

Slide 32

Slide 32 text

FirebaseVisionImage

Slide 33

Slide 33 text

• 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

Slide 34

Slide 34 text

• 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

Slide 35

Slide 35 text

• 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

Slide 36

Slide 36 text

• 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

Slide 37

Slide 37 text

Done!

Slide 38

Slide 38 text

Save a image A N D R O I D H I T C H H I K E R

Slide 39

Slide 39 text

to External Storage

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

Global Screenshot

Slide 42

Slide 42 text

• app/AndroidManifest.xml Global Screenshot T O E X T E R N A L S T O R A G E

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

But, deprecated in Q

Slide 46

Slide 46 text

• app/AndroidManifest.xml Avoid temporarily Link: https://developer.android.com/.../scoped-storage#opt-out-of-filtered-view

Slide 47

Slide 47 text

Done!

Slide 48

Slide 48 text

• জ ࢸ੿ীࢲ ӂೠਸ ࣻزਵ۽ ߸҃ೡ ࣻب ੓णפ׮. • ஠ݫۄо ೙ਃೞ׮ݶ natario1/CameraViewܳ ୶ୌ೤פ׮. • ੷੢ػ ੉޷૑ܳ ࠛ۞ৢ ٸח Common Intentܳ ੉ਊ೧ࠁࣁਃ. • FirebaseVisionImageܳ ࢎਊೞৈ Bitmapਵ۽ औѱ ߄Ե ࣻ ੓णפ׮. • ੉޷૑ܳ ੷੢ೡ ٸ, Global Screenshot ௏٘ܳ ଵҊ೧ࠁࣁਃ. Summary Link: https://github.com/fornewid/tensorflow-style-transfer-android

Slide 49

Slide 49 text

Q & A A N D R O I D H I T C H H I K E R