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 */ 16package android.hardware.camera2.cts.rs; 17 18import android.graphics.Bitmap; 19import android.graphics.Color; 20import android.renderscript.Allocation; 21import android.renderscript.Element; 22import android.renderscript.RenderScript; 23import android.renderscript.ScriptIntrinsicHistogram; 24 25/** 26 * Utility class providing methods for various pixel-wise ARGB bitmap operations. 27 */ 28public class BitmapUtils { 29 private static final String TAG = "BitmapUtils"; 30 private static final int COLOR_BIT_DEPTH = 256; 31 32 public static int A = 3; 33 public static int R = 0; 34 public static int G = 1; 35 public static int B = 2; 36 public static int NUM_CHANNELS = 4; 37 38 /** 39 * Return the histograms for each color channel (interleaved). 40 * 41 * @param rs a {@link RenderScript} context to use. 42 * @param bmap a {@link Bitmap} to generate the histograms for. 43 * @return an array containing NUM_CHANNELS * COLOR_BIT_DEPTH histogram bucket values, with 44 * the color channels interleaved. 45 */ 46 public static int[] calcHistograms(RenderScript rs, Bitmap bmap) { 47 ScriptIntrinsicHistogram hist = ScriptIntrinsicHistogram.create(rs, Element.U8_4(rs)); 48 Allocation sums = Allocation.createSized(rs, Element.I32_4(rs), COLOR_BIT_DEPTH); 49 50 // Setup input allocation (ARGB 8888 bitmap). 51 Allocation input = Allocation.createFromBitmap(rs, bmap); 52 53 hist.setOutput(sums); 54 hist.forEach(input); 55 int[] output = new int[COLOR_BIT_DEPTH * NUM_CHANNELS]; 56 sums.copyTo(output); 57 return output; 58 } 59 60 /** 61 * Find the difference between two bitmaps using average of per-pixel differences. 62 * 63 * @param a first {@link android.graphics.Bitmap}. 64 * @param b second {@link android.graphics.Bitmap}. 65 * @return the difference. 66 */ 67 public static double calcDifferenceMetric(Bitmap a, Bitmap b) { 68 if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) { 69 throw new IllegalArgumentException("Bitmap dimensions for arguments do not match a=" + 70 a.getWidth() + "x" + a.getHeight() + ", b=" + b.getWidth() + "x" + 71 b.getHeight()); 72 } 73 // TODO: Optimize this in renderscript to avoid copy. 74 int[] aPixels = new int[a.getHeight() * a.getWidth()]; 75 int[] bPixels = new int[aPixels.length]; 76 a.getPixels(aPixels, /*offset*/0, /*stride*/a.getWidth(), /*x*/0, /*y*/0, a.getWidth(), 77 a.getHeight()); 78 b.getPixels(bPixels, /*offset*/0, /*stride*/b.getWidth(), /*x*/0, /*y*/0, b.getWidth(), 79 b.getHeight()); 80 double diff = 0; 81 for (int i = 0; i < aPixels.length; i++) { 82 int aPix = aPixels[i]; 83 int bPix = bPixels[i]; 84 85 diff += Math.abs(Color.red(aPix) - Color.red(bPix)); // red 86 diff += Math.abs(Color.green(aPix) - Color.green(bPix)); // green 87 diff += Math.abs(Color.blue(aPix) - Color.blue(bPix)); // blue 88 } 89 diff /= (aPixels.length * 3); 90 return diff; 91 } 92 93} 94