Skip to content

Instantly share code, notes, and snippets.

@ashwin-sp
Created February 18, 2018 19:02
Show Gist options
  • Save ashwin-sp/9f1f14fea588a64942510cd935c5fd1a to your computer and use it in GitHub Desktop.
Save ashwin-sp/9f1f14fea588a64942510cd935c5fd1a to your computer and use it in GitHub Desktop.
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