Home | History | Annotate | Download | only in info
      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 
     17 package com.android.gallery3d.filtershow.info;
     18 
     19 import android.content.Context;
     20 import android.graphics.Bitmap;
     21 import android.graphics.Canvas;
     22 import android.graphics.Color;
     23 import android.graphics.Paint;
     24 import android.graphics.Path;
     25 import android.graphics.PorterDuff;
     26 import android.graphics.PorterDuffXfermode;
     27 import android.os.AsyncTask;
     28 import android.util.AttributeSet;
     29 import android.view.View;
     30 
     31 public 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