1/* 2 * Copyright (C) 2013 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 17package com.android.gallery3d.filtershow.info; 18 19import android.content.Context; 20import android.graphics.Bitmap; 21import android.graphics.Canvas; 22import android.graphics.Color; 23import android.graphics.Paint; 24import android.graphics.Path; 25import android.graphics.PorterDuff; 26import android.graphics.PorterDuffXfermode; 27import android.os.AsyncTask; 28import android.util.AttributeSet; 29import android.view.View; 30 31public class HistogramView extends View { 32 33 private Bitmap mBitmap; 34 private Paint mPaint = new Paint(); 35 private int[] redHistogram = new int[256]; 36 private int[] greenHistogram = new int[256]; 37 private int[] blueHistogram = new int[256]; 38 private Path mHistoPath = new Path(); 39 40 class ComputeHistogramTask extends AsyncTask<Bitmap, Void, int[]> { 41 @Override 42 protected int[] doInBackground(Bitmap... params) { 43 int[] histo = new int[256 * 3]; 44 Bitmap bitmap = params[0]; 45 int w = bitmap.getWidth(); 46 int h = bitmap.getHeight(); 47 int[] pixels = new int[w * h]; 48 bitmap.getPixels(pixels, 0, w, 0, 0, w, h); 49 for (int i = 0; i < w; i++) { 50 for (int j = 0; j < h; j++) { 51 int index = j * w + i; 52 int r = Color.red(pixels[index]); 53 int g = Color.green(pixels[index]); 54 int b = Color.blue(pixels[index]); 55 histo[r]++; 56 histo[256 + g]++; 57 histo[512 + b]++; 58 } 59 } 60 return histo; 61 } 62 63 @Override 64 protected void onPostExecute(int[] result) { 65 System.arraycopy(result, 0, redHistogram, 0, 256); 66 System.arraycopy(result, 256, greenHistogram, 0, 256); 67 System.arraycopy(result, 512, blueHistogram, 0, 256); 68 invalidate(); 69 } 70 } 71 72 public HistogramView(Context context, AttributeSet attrs) { 73 super(context, attrs); 74 } 75 76 public void setBitmap(Bitmap bitmap) { 77 mBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); 78 new ComputeHistogramTask().execute(mBitmap); 79 } 80 81 private void drawHistogram(Canvas canvas, int[] histogram, int color, PorterDuff.Mode mode) { 82 int max = 0; 83 for (int i = 0; i < histogram.length; i++) { 84 if (histogram[i] > max) { 85 max = histogram[i]; 86 } 87 } 88 float w = getWidth(); // - Spline.curveHandleSize(); 89 float h = getHeight(); // - Spline.curveHandleSize() / 2.0f; 90 float dx = 0; // Spline.curveHandleSize() / 2.0f; 91 float wl = w / histogram.length; 92 float wh = h / max; 93 94 mPaint.reset(); 95 mPaint.setAntiAlias(true); 96 mPaint.setARGB(100, 255, 255, 255); 97 mPaint.setStrokeWidth((int) Math.ceil(wl)); 98 99 // Draw grid 100 mPaint.setStyle(Paint.Style.STROKE); 101 canvas.drawRect(dx, 0, dx + w, h, mPaint); 102 canvas.drawLine(dx + w / 3, 0, dx + w / 3, h, mPaint); 103 canvas.drawLine(dx + 2 * w / 3, 0, dx + 2 * w / 3, h, mPaint); 104 105 mPaint.setStyle(Paint.Style.FILL); 106 mPaint.setColor(color); 107 mPaint.setStrokeWidth(6); 108 mPaint.setXfermode(new PorterDuffXfermode(mode)); 109 mHistoPath.reset(); 110 mHistoPath.moveTo(dx, h); 111 boolean firstPointEncountered = false; 112 float prev = 0; 113 float last = 0; 114 for (int i = 0; i < histogram.length; i++) { 115 float x = i * wl + dx; 116 float l = histogram[i] * wh; 117 if (l != 0) { 118 float v = h - (l + prev) / 2.0f; 119 if (!firstPointEncountered) { 120 mHistoPath.lineTo(x, h); 121 firstPointEncountered = true; 122 } 123 mHistoPath.lineTo(x, v); 124 prev = l; 125 last = x; 126 } 127 } 128 mHistoPath.lineTo(last, h); 129 mHistoPath.lineTo(w, h); 130 mHistoPath.close(); 131 canvas.drawPath(mHistoPath, mPaint); 132 mPaint.setStrokeWidth(2); 133 mPaint.setStyle(Paint.Style.STROKE); 134 mPaint.setARGB(255, 200, 200, 200); 135 canvas.drawPath(mHistoPath, mPaint); 136 } 137 138 public void onDraw(Canvas canvas) { 139 canvas.drawARGB(0, 0, 0, 0); 140 drawHistogram(canvas, redHistogram, Color.RED, PorterDuff.Mode.SCREEN); 141 drawHistogram(canvas, greenHistogram, Color.GREEN, PorterDuff.Mode.SCREEN); 142 drawHistogram(canvas, blueHistogram, Color.BLUE, PorterDuff.Mode.SCREEN); 143 } 144} 145