1 /* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.hardware.camera2.cts.rs; 17 18 import android.graphics.Bitmap; 19 import android.graphics.Color; 20 21 /** 22 * Utility class providing methods for various pixel-wise ARGB bitmap operations. 23 */ 24 public class BitmapUtils { 25 private static final String TAG = "BitmapUtils"; 26 private static final int COLOR_BIT_DEPTH = 256; 27 public static int NUM_CHANNELS = 4; 28 29 // Some stats output from comparing two Bitmap using calcDifferenceMetric 30 public static class BitmapCompareResult { 31 // difference between two bitmaps using average of per-pixel differences. 32 public double mDiff; 33 // If the LHS Bitmap has same RGB values for all pixels 34 public boolean mLhsFlat; 35 // If the RHS Bitmap has same RGB values for all pixels 36 public boolean mRhsFlat; 37 // The R/G/B average pixel value of LHS Bitmap 38 public double[] mLhsAverage = new double[3]; 39 // The R/G/B average pixel value of RHS Bitmap 40 public double[] mRhsAverage = new double[3]; 41 } 42 43 /** 44 * Compare two bitmaps and also return some statistics about the two Bitmap. 45 * 46 * @param a first {@link android.graphics.Bitmap}. 47 * @param b second {@link android.graphics.Bitmap}. 48 * @return the results in a BitmapCompareResult 49 */ compareBitmap(Bitmap a, Bitmap b)50 public static BitmapCompareResult compareBitmap(Bitmap a, Bitmap b) { 51 if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) { 52 throw new IllegalArgumentException("Bitmap dimensions for arguments do not match a=" + 53 a.getWidth() + "x" + a.getHeight() + ", b=" + b.getWidth() + "x" + 54 b.getHeight()); 55 } 56 57 int[] aPixels = new int[a.getHeight() * a.getWidth()]; 58 int[] bPixels = new int[aPixels.length]; 59 a.getPixels(aPixels, /*offset*/0, /*stride*/a.getWidth(), /*x*/0, /*y*/0, a.getWidth(), 60 a.getHeight()); 61 b.getPixels(bPixels, /*offset*/0, /*stride*/b.getWidth(), /*x*/0, /*y*/0, b.getWidth(), 62 b.getHeight()); 63 double diff = 0; 64 double[] aSum = new double[3]; 65 double[] bSum = new double[3]; 66 int[] aFirstPix = new int[3]; 67 int[] bFirstPix = new int[3]; 68 aFirstPix[0] = Color.red(aPixels[0]); 69 aFirstPix[1] = Color.green(aPixels[1]); 70 aFirstPix[2] = Color.blue(aPixels[2]); 71 bFirstPix[0] = Color.red(bPixels[0]); 72 bFirstPix[1] = Color.green(bPixels[1]); 73 bFirstPix[2] = Color.blue(bPixels[2]); 74 boolean isAFlat = true, isBFlat = true; 75 76 for (int i = 0; i < aPixels.length; i++) { 77 int aPix = aPixels[i]; 78 int bPix = bPixels[i]; 79 int aR = Color.red(aPix); 80 int aG = Color.green(aPix); 81 int aB = Color.blue(aPix); 82 int bR = Color.red(bPix); 83 int bG = Color.green(bPix); 84 int bB = Color.blue(bPix); 85 aSum[0] += aR; 86 aSum[1] += aG; 87 aSum[2] += aB; 88 bSum[0] += bR; 89 bSum[1] += bG; 90 bSum[2] += bB; 91 92 if (isAFlat && (aR != aFirstPix[0] || aG != aFirstPix[1] || aB != aFirstPix[2])) { 93 isAFlat = false; 94 } 95 96 if (isBFlat && (bR != bFirstPix[0] || bG != bFirstPix[1] || bB != bFirstPix[2])) { 97 isBFlat = false; 98 } 99 100 diff += Math.abs(aR - bR); // red 101 diff += Math.abs(aG - bG); // green 102 diff += Math.abs(aB - bB); // blue 103 } 104 diff /= (aPixels.length * 3); 105 BitmapCompareResult result = new BitmapCompareResult(); 106 result.mDiff = diff; 107 result.mLhsFlat = isAFlat; 108 result.mRhsFlat = isBFlat; 109 for (int i = 0; i < 3; i++) { 110 result.mLhsAverage[i] = aSum[i] / aPixels.length; 111 result.mRhsAverage[i] = bSum[i] / bPixels.length; 112 } 113 return result; 114 } 115 116 /** 117 * Find the difference between two bitmaps using average of per-pixel differences. 118 * 119 * @param a first {@link android.graphics.Bitmap}. 120 * @param b second {@link android.graphics.Bitmap}. 121 * @return the difference. 122 */ calcDifferenceMetric(Bitmap a, Bitmap b)123 public static double calcDifferenceMetric(Bitmap a, Bitmap b) { 124 BitmapCompareResult result = compareBitmap(a, b); 125 return result.mDiff; 126 } 127 128 } 129