Created
February 18, 2018 19:02
-
-
Save ashwin-sp/9f1f14fea588a64942510cd935c5fd1a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ImagePreprocessor { | |
private static final boolean SAVE_PREVIEW_BITMAP = false; | |
private Bitmap rgbFrameBitmap; | |
private Bitmap croppedBitmap; | |
public ImagePreprocessor() { | |
this.croppedBitmap = Bitmap.createBitmap(224, 224, | |
Bitmap.Config.ARGB_8888); | |
this.rgbFrameBitmap = Bitmap.createBitmap(CameraHandler.IMAGE_WIDTH, | |
CameraHandler.IMAGE_HEIGHT, Bitmap.Config.ARGB_8888); | |
} | |
public Bitmap preprocessImage(final Image image) { | |
if (image == null) { | |
return null; | |
} | |
Assert.assertEquals("Invalid size width", rgbFrameBitmap.getWidth(), image.getWidth()); | |
Assert.assertEquals("Invalid size height", rgbFrameBitmap.getHeight(), image.getHeight()); | |
if (croppedBitmap != null && rgbFrameBitmap != null) { | |
ByteBuffer bb = image.getPlanes()[0].getBuffer(); | |
rgbFrameBitmap = BitmapFactory.decodeStream(new ByteBufferBackedInputStream(bb)); | |
cropAndRescaleBitmap(rgbFrameBitmap, croppedBitmap, 0); | |
} | |
image.close(); | |
// For debugging | |
if (SAVE_PREVIEW_BITMAP) { | |
saveBitmap(croppedBitmap); | |
} | |
return croppedBitmap; | |
} | |
private static class ByteBufferBackedInputStream extends InputStream { | |
ByteBuffer buf; | |
public ByteBufferBackedInputStream(ByteBuffer buf) { | |
this.buf = buf; | |
} | |
public int read() throws IOException { | |
if (!buf.hasRemaining()) { | |
return -1; | |
} | |
return buf.get() & 0xFF; | |
} | |
public int read(byte[] bytes, int off, int len) | |
throws IOException { | |
if (!buf.hasRemaining()) { | |
return -1; | |
} | |
len = Math.min(len, buf.remaining()); | |
buf.get(bytes, off, len); | |
return len; | |
} | |
} | |
/** | |
* Saves a Bitmap object to disk for analysis. | |
* | |
* @param bitmap The bitmap to save. | |
*/ | |
public static void saveBitmap(final Bitmap bitmap) { | |
final File file = new File(Environment.getExternalStoragePublicDirectory( | |
Environment.DIRECTORY_PICTURES), "preview.png"); | |
Log.d("ImageHelper", String.format("Saving %dx%d bitmap to %s.", | |
bitmap.getWidth(), bitmap.getHeight(), file.getAbsolutePath())); | |
if (file.exists()) { | |
file.delete(); | |
} | |
try (FileOutputStream fs = new FileOutputStream(file); | |
BufferedOutputStream out = new BufferedOutputStream(fs)) { | |
bitmap.compress(Bitmap.CompressFormat.PNG, 99, out); | |
} catch (final Exception e) { | |
Log.w("ImageHelper", "Could not save image for debugging. " + e.getMessage()); | |
} | |
} | |
public static void cropAndRescaleBitmap(final Bitmap src, final Bitmap dst, int sensorOrientation) { | |
Assert.assertEquals(dst.getWidth(), dst.getHeight()); | |
final float minDim = Math.min(src.getWidth(), src.getHeight()); | |
final Matrix matrix = new Matrix(); | |
// We only want the center square out of the original rectangle. | |
final float translateX = -Math.max(0, (src.getWidth() - minDim) / 2); | |
final float translateY = -Math.max(0, (src.getHeight() - minDim) / 2); | |
matrix.preTranslate(translateX, translateY); | |
final float scaleFactor = dst.getHeight() / minDim; | |
matrix.postScale(scaleFactor, scaleFactor); | |
// Rotate around the center if necessary. | |
if (sensorOrientation != 0) { | |
matrix.postTranslate(-dst.getWidth() / 2.0f, -dst.getHeight() / 2.0f); | |
matrix.postRotate(sensorOrientation); | |
matrix.postTranslate(dst.getWidth() / 2.0f, dst.getHeight() / 2.0f); | |
} | |
final Canvas canvas = new Canvas(dst); | |
canvas.drawBitmap(src, matrix, null); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment