Technical causes and countermeasures for points addicted to Android apps & Kotlin (3. Processing related to Android images)

3. 3. * Android * image processing

Since this application uses * OpenCV * * Mat * (1 row 2D matrix), conversion between * Bitmap * and * Mat * is required. Previously, I told you that I decided to incorporate a process to rotate the image instead of prohibiting the terminal rotation at the screen transition (fragment) process, but there was a problem with the image image mirroring process.

3.1 * createTempFile () * (unique file name) processing of * File * class

In this application, the image of the gallery or the image taken by the camera is temporarily saved as a file.

If you execute this application with * API 24 / Android 7.0 / Nougat * or above, an exception will occur in * createTempFile * (unique file name) processing.

In * API 24 / Android 7.0 / Nougat * and above, an exception will occur in the processing after * isInvalid () * in * File.createTempFile () *.

Initially, I tried to use * Files.createTempFile () , but the * Files * class is only implemented since * API 26 / Android 8.0 / Oreo * ( Java SE SDK 7 *). We don't care about * createTempFile () * separately, we add absolute time when we instantiate the * File * class to create a unique file name.

Unique file name


// .....Abbreviation
	fun getImageFile(context: Context, child: String): File {
		context.filesDir.let { path ->
			if (!path.exists()) path.mkdir()
			return File("$path$child-${System.currentTimeMillis()}$SUFFIX_IMAGE") // $SUFFIX_IMAGE → ".jpg "
		}
	}
// .....Abbreviation

3.2 Image image mirror processing using * OpenCV *

In this application, after pasting the image image after the screen transition, touch the [Mirror] button on the image image display (processing) screen to perform mirror processing of the image image.

For mirror processing, * Core.flip () * of * OpenCV * is used, but if mirroring is repeated several times, the image will be degraded.

Image image reading → * bitmapToMat (Bitmap → Mat) * → * Core.flip () * → * matToBitmap (Mat → Bitmap) * → When saving an image image * Bitmap * compression format is * JPEG *, lossy compression , Some data will be missing. Normally, the deterioration is so inconspicuous that it is difficult for the human eye to judge, but by repeatedly compressing and saving the image image, the deterioration became noticeable.

Image The image was saved by changing the * Bitmap * compression format to * WEBP * (lossless compression compatible).

Bitmap compression format (WEBP)


// .....Abbreviation
	ByteArrayOutputStream().let { outStream ->
		bitMap.compress(Bitmap.CompressFormat.WEBP, 100, outStream)
		FileOutputStream(argument).apply {
			outStream.writeTo(this)
			close()
		}
	}
// .....Abbreviation

3.3 Seamless composition processing using * OpenCV *

In this application, after pasting two image images, touch the [Enter] button on the image image display (processing) screen to perform seamless composition processing of the image images.

In the seamless compositing process, * OpenCV 's * Photo.seamlessClone () * is used, but for compositing (* want to ) original image and compositing ( want to *) destination image and mask If you specify an image, an error ( assertion failed *) will occur.

An error will occur if the size of the original image to be combined () and the image to be combined () are not the same. Also, an error will occur for 4-channel images that include transparency. (Finally noticed in the * OpenCV * source and the * Photo.seamlessClone () * documentation)

Make the size of the original image to be combined (** want to ) and the image to be combined ( want to be **) the same. In addition, each image is specified by 3 channels of 8 bits.

Image conversion of the same size


// .....Abbreviation
	private fun createThumbnailBitmap(
		bitMap: Bitmap, reqWidth: Int, reqHeight: Int, filter: Boolean
	): Bitmap = Bitmap.createScaledBitmap(bitMap, reqWidth, reqHeight, filter)
// .....Abbreviation

Bitmap to Mat conversion


// .....Abbreviation
	fun bitmapToMat(bitMap: Bitmap?, colorCode: Int): Mat {
		return Mat(bitMap?.height ?: 0, bitMap?.width ?: 0, CvType.CV_8UC3).apply {
			Utils.bitmapToMat(bitMap,this, false)
			Imgproc.cvtColor(this, this, colorCode, depth())
		}
	}
// .....Abbreviation

3.4 Seamless composite image gallery registration process

In this application, after pasting two image images, touch the [Enter] button on the image image display (processing) screen to perform seamless composition processing of the image images. After the screen transition, touch the [Save] button on the seamless composition result screen to register the gallery.

Even if the seamlessly composited image is saved in the external area, it is not recognized by * MediaScannerConnection.scanFile () * and is not registered in the gallery.

If you save the seamlessly composited image in the external data area (* Context.getExternalFilesDir () *), it will not be recognized by * MediaScannerConnection.scanFile () *.

By saving the seamlessly composited image in the external public shared area (* Environment.getExternalStoragePublicDirectory () *), it was recognized by * MediaScannerConnection.scanFile () *.

External public shared area storage location


// .....Abbreviation
	fun getMixingExternalImageFile(): File {
		//The internal data area is not used because the gallery cannot be registered except for the external public shared area.
		File(
			Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
			PATH_MIXING_IMAGE // → "SeamlessCollage"
		).let { file ->
			if (!file.exists()) file.mkdir()
			return File("$file$FILE_MIXING_IMAGE-${System.currentTimeMillis()}$SUFFIX_IMAGE")
		}
	}
// .....Abbreviation

python


// .....Abbreviation
	MediaScannerConnection.scanFile(
		context,
		arrayOf(strUri),
		arrayOf("image/jpeg"),
		this // MediaScannerConnection.OnScanCompletedListener Callback
	)
// .....Abbreviation

Link

Technical causes and countermeasures for the first Android app & Kotlin addiction 1. Android screen transition (fragment) processing 2. Processing related to Android camera function

Recommended Posts

Technical causes and countermeasures for points addicted to Android apps & Kotlin (3. Processing related to Android images)
Technical causes and countermeasures for points addicted to Android apps & Kotlin (1. Android screen transition (fragment) processing)
Technical causes and countermeasures for the points that I was addicted to with the Android app & Kotlin (2. Processing related to the camera function of Android *)
Technical causes and countermeasures for the points I was addicted to with the first Android app & Kotlin
Convert all Android apps (Java) to Kotlin
Summary of good points and precautions when converting Java Android application to Kotlin
Specify Java / Kotlin compile-time options for Android apps
VSCode Java Debugger for Java Build failed Causes and countermeasures