1 package com.android.nn.benchmark.imageprocessors;
2 
3 import android.content.res.AssetManager;
4 import android.graphics.Bitmap;
5 import android.graphics.BitmapFactory;
6 
7 import com.android.nn.benchmark.core.ImageProcessorInterface;
8 
9 import java.io.File;
10 import java.io.IOException;
11 import java.io.RandomAccessFile;
12 import java.nio.ByteBuffer;
13 import java.nio.ByteOrder;
14 import java.nio.channels.FileChannel;
15 
16 /**
17  * Inception image prepreocessor. Crops image to a centered square, 85% of smallest original
18  * dimensions. Scales to target size and quantizes if needed.
19  */
20 
21 public class Inception implements ImageProcessorInterface {
preprocess(int datasize, float quantScale, float quantZeroPoint, int imageDimension, AssetManager assetManager, String imageFileName, File cacheDir, ByteBuffer outputBuffer)22     public void preprocess(int datasize, float quantScale, float quantZeroPoint,
23                            int imageDimension, AssetManager assetManager,
24                            String imageFileName, File cacheDir, ByteBuffer outputBuffer)
25             throws IOException {
26         Bitmap origBitmap = BitmapFactory.decodeStream(assetManager.open(imageFileName));
27 
28         int croppedSize = (int)(0.875f * Math.min(origBitmap.getWidth(), origBitmap.getHeight()));
29         int x = origBitmap.getWidth() / 2 - croppedSize / 2;
30         int y = origBitmap.getHeight() / 2 - croppedSize / 2;
31 
32         Bitmap centeredBitmap = Bitmap.createBitmap(origBitmap, x, y, croppedSize, croppedSize);
33         // FileOutputStream cb = new FileOutputStream(cacheDir.getAbsolutePath() +  "/c.jpeg");
34         // centeredBitmap.compress(Bitmap.CompressFormat.JPEG, 90, cb);
35         Bitmap scaledBitmap = Bitmap.createScaledBitmap(centeredBitmap, imageDimension,
36                 imageDimension, true);
37         // FileOutputStream sb = new FileOutputStream(cacheDir.getAbsolutePath() + "/s.jpeg");
38         // scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 90, sb);
39 
40         int[] pixels = new int[imageDimension * imageDimension];
41         scaledBitmap.getPixels(pixels, 0, imageDimension, 0, 0, imageDimension, imageDimension);
42 
43         // Some of the bitmap operations may return the same underlying bitmap, recycle only
44         // at the end.
45         scaledBitmap.recycle();
46         centeredBitmap.recycle();
47         origBitmap.recycle();
48 
49         outputBuffer.clear();
50         outputBuffer.order(ByteOrder.LITTLE_ENDIAN);
51         for (int i = 0; i < imageDimension * imageDimension; i++) {
52             // Needs to use more bits in intermediates since bytes are signed.
53             // Results of bitwise ops are ints.
54             //
55             int redOrig = (pixels[i] >> 16) & 0xFF;
56             int greenOrig = (pixels[i] >> 8) & 0xFF;
57             int blueOrig = pixels[i] & 0xFF;
58 
59             float redFloat = (redOrig * 2.0f / 255.0f) - 1.0f;
60             float greenFloat = (greenOrig * 2.0f / 255.0f) - 1.0f;
61             float blueFloat = (blueOrig * 2.0f / 255.0f) - 1.0f;
62 
63             if (datasize == 4) {
64                 outputBuffer.putFloat(redFloat);
65                 outputBuffer.putFloat(greenFloat);
66                 outputBuffer.putFloat(blueFloat);
67             } else {
68                 int redByte = (int)(redFloat / quantScale + quantZeroPoint);
69                 int greenByte = (int)(greenFloat / quantScale + quantZeroPoint);
70                 int blueByte = (int)(blueFloat / quantScale + quantZeroPoint);
71                 outputBuffer.put((byte)(redByte & 0xff));
72                 outputBuffer.put((byte)(greenByte & 0xff));
73                 outputBuffer.put((byte)(blueByte & 0xff));
74             }
75         }
76     }
77 }
78