Home | History | Annotate | Download | only in levels
      1 /*
      2  * Copyright (C) 2012 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.rs.levels;
     18 
     19 import android.app.Activity;
     20 import android.graphics.Bitmap;
     21 import android.graphics.BitmapFactory;
     22 import android.graphics.Canvas;
     23 import android.os.Bundle;
     24 import android.renderscript.Matrix3f;
     25 import android.util.Log;
     26 import android.view.View;
     27 import android.widget.ImageView;
     28 import android.widget.SeekBar;
     29 import android.widget.TextView;
     30 
     31 public class LevelsDalvikActivity extends Activity
     32                                   implements SeekBar.OnSeekBarChangeListener {
     33     private final String TAG = "Img";
     34     private Bitmap mBitmapIn;
     35     private Bitmap mBitmapOut;
     36     private float mInBlack = 0.0f;
     37     private SeekBar mInBlackSeekBar;
     38     private float mOutBlack = 0.0f;
     39     private SeekBar mOutBlackSeekBar;
     40     private float mInWhite = 255.0f;
     41     private SeekBar mInWhiteSeekBar;
     42     private float mOutWhite = 255.0f;
     43     private SeekBar mOutWhiteSeekBar;
     44     private float mGamma = 1.0f;
     45     private SeekBar mGammaSeekBar;
     46     private float mSaturation = 1.0f;
     47     private SeekBar mSaturationSeekBar;
     48     private TextView mBenchmarkResult;
     49     private ImageView mDisplayView;
     50 
     51     Matrix3f satMatrix = new Matrix3f();
     52     float mInWMinInB;
     53     float mOutWMinOutB;
     54     float mOverInWMinInB;
     55 
     56     int mInPixels[];
     57     int mOutPixels[];
     58 
     59     private void setLevels() {
     60         mInWMinInB = mInWhite - mInBlack;
     61         mOutWMinOutB = mOutWhite - mOutBlack;
     62         mOverInWMinInB = 1.f / mInWMinInB;
     63     }
     64 
     65     private void setSaturation() {
     66         float rWeight = 0.299f;
     67         float gWeight = 0.587f;
     68         float bWeight = 0.114f;
     69         float oneMinusS = 1.0f - mSaturation;
     70 
     71         satMatrix.set(0, 0, oneMinusS * rWeight + mSaturation);
     72         satMatrix.set(0, 1, oneMinusS * rWeight);
     73         satMatrix.set(0, 2, oneMinusS * rWeight);
     74         satMatrix.set(1, 0, oneMinusS * gWeight);
     75         satMatrix.set(1, 1, oneMinusS * gWeight + mSaturation);
     76         satMatrix.set(1, 2, oneMinusS * gWeight);
     77         satMatrix.set(2, 0, oneMinusS * bWeight);
     78         satMatrix.set(2, 1, oneMinusS * bWeight);
     79         satMatrix.set(2, 2, oneMinusS * bWeight + mSaturation);
     80     }
     81 
     82     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
     83         if (fromUser) {
     84             if (seekBar == mInBlackSeekBar) {
     85                 mInBlack = (float)progress;
     86                 setLevels();
     87             } else if (seekBar == mOutBlackSeekBar) {
     88                 mOutBlack = (float)progress;
     89                 setLevels();
     90             } else if (seekBar == mInWhiteSeekBar) {
     91                 mInWhite = (float)progress + 127.0f;
     92                 setLevels();
     93             } else if (seekBar == mOutWhiteSeekBar) {
     94                 mOutWhite = (float)progress + 127.0f;
     95                 setLevels();
     96             } else if (seekBar == mGammaSeekBar) {
     97                 mGamma = (float)progress/100.0f;
     98                 mGamma = Math.max(mGamma, 0.1f);
     99                 mGamma = 1.0f / mGamma;
    100             } else if (seekBar == mSaturationSeekBar) {
    101                 mSaturation = (float)progress / 50.0f;
    102                 setSaturation();
    103             }
    104 
    105             filter();
    106             mDisplayView.invalidate();
    107         }
    108     }
    109 
    110     public void onStartTrackingTouch(SeekBar seekBar) {
    111     }
    112 
    113     public void onStopTrackingTouch(SeekBar seekBar) {
    114     }
    115 
    116     @Override
    117     protected void onCreate(Bundle savedInstanceState) {
    118         super.onCreate(savedInstanceState);
    119         setContentView(R.layout.main);
    120 
    121         mBitmapIn = loadBitmap(R.drawable.city);
    122         mBitmapOut = loadBitmap(R.drawable.city);
    123 
    124         mDisplayView = (ImageView) findViewById(R.id.display);
    125         mDisplayView.setImageBitmap(mBitmapOut);
    126 
    127         mInBlackSeekBar = (SeekBar)findViewById(R.id.inBlack);
    128         mInBlackSeekBar.setOnSeekBarChangeListener(this);
    129         mInBlackSeekBar.setMax(128);
    130         mInBlackSeekBar.setProgress(0);
    131         mOutBlackSeekBar = (SeekBar)findViewById(R.id.outBlack);
    132         mOutBlackSeekBar.setOnSeekBarChangeListener(this);
    133         mOutBlackSeekBar.setMax(128);
    134         mOutBlackSeekBar.setProgress(0);
    135 
    136         mInWhiteSeekBar = (SeekBar)findViewById(R.id.inWhite);
    137         mInWhiteSeekBar.setOnSeekBarChangeListener(this);
    138         mInWhiteSeekBar.setMax(128);
    139         mInWhiteSeekBar.setProgress(128);
    140         mOutWhiteSeekBar = (SeekBar)findViewById(R.id.outWhite);
    141         mOutWhiteSeekBar.setOnSeekBarChangeListener(this);
    142         mOutWhiteSeekBar.setMax(128);
    143         mOutWhiteSeekBar.setProgress(128);
    144 
    145         mGammaSeekBar = (SeekBar)findViewById(R.id.inGamma);
    146         mGammaSeekBar.setOnSeekBarChangeListener(this);
    147         mGammaSeekBar.setMax(150);
    148         mGammaSeekBar.setProgress(100);
    149 
    150         mSaturationSeekBar = (SeekBar)findViewById(R.id.inSaturation);
    151         mSaturationSeekBar.setOnSeekBarChangeListener(this);
    152         mSaturationSeekBar.setProgress(50);
    153 
    154         mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText);
    155         mBenchmarkResult.setText("Result: not run");
    156 
    157         mInPixels = new int[mBitmapIn.getHeight() * mBitmapIn.getWidth()];
    158         mOutPixels = new int[mBitmapOut.getHeight() * mBitmapOut.getWidth()];
    159         mBitmapIn.getPixels(mInPixels, 0, mBitmapIn.getWidth(), 0, 0,
    160                             mBitmapIn.getWidth(), mBitmapIn.getHeight());
    161 
    162         setLevels();
    163         setSaturation();
    164         filter();
    165     }
    166 
    167     private Bitmap loadBitmap(int resource) {
    168         final BitmapFactory.Options options = new BitmapFactory.Options();
    169         options.inPreferredConfig = Bitmap.Config.ARGB_8888;
    170         Bitmap b = BitmapFactory.decodeResource(getResources(), resource, options);
    171         Bitmap b2 = Bitmap.createBitmap(b.getWidth(), b.getHeight(), b.getConfig());
    172         Canvas c = new Canvas(b2);
    173         c.drawBitmap(b, 0, 0, null);
    174         b.recycle();
    175         return b2;
    176     }
    177 
    178 
    179 
    180     private void filter() {
    181         final float[] m = satMatrix.getArray();
    182 
    183         for (int i=0; i < mInPixels.length; i++) {
    184             float r = (float)(mInPixels[i] & 0xff);
    185             float g = (float)((mInPixels[i] >> 8) & 0xff);
    186             float b = (float)((mInPixels[i] >> 16) & 0xff);
    187 
    188             float tr = r * m[0] + g * m[3] + b * m[6];
    189             float tg = r * m[1] + g * m[4] + b * m[7];
    190             float tb = r * m[2] + g * m[5] + b * m[8];
    191             r = tr;
    192             g = tg;
    193             b = tb;
    194 
    195             if (r < 0.f) r = 0.f;
    196             if (r > 255.f) r = 255.f;
    197             if (g < 0.f) g = 0.f;
    198             if (g > 255.f) g = 255.f;
    199             if (b < 0.f) b = 0.f;
    200             if (b > 255.f) b = 255.f;
    201 
    202             r = (r - mInBlack) * mOverInWMinInB;
    203             g = (g - mInBlack) * mOverInWMinInB;
    204             b = (b - mInBlack) * mOverInWMinInB;
    205 
    206             if (mGamma != 1.0f) {
    207                 r = (float)java.lang.Math.pow(r, mGamma);
    208                 g = (float)java.lang.Math.pow(g, mGamma);
    209                 b = (float)java.lang.Math.pow(b, mGamma);
    210             }
    211 
    212             r = (r * mOutWMinOutB) + mOutBlack;
    213             g = (g * mOutWMinOutB) + mOutBlack;
    214             b = (b * mOutWMinOutB) + mOutBlack;
    215 
    216             if (r < 0.f) r = 0.f;
    217             if (r > 255.f) r = 255.f;
    218             if (g < 0.f) g = 0.f;
    219             if (g > 255.f) g = 255.f;
    220             if (b < 0.f) b = 0.f;
    221             if (b > 255.f) b = 255.f;
    222 
    223             mOutPixels[i] = ((int)r) + (((int)g) << 8) + (((int)b) << 16)
    224                             + (mInPixels[i] & 0xff000000);
    225         }
    226 
    227         mBitmapOut.setPixels(mOutPixels, 0, mBitmapOut.getWidth(), 0, 0,
    228                              mBitmapOut.getWidth(), mBitmapOut.getHeight());
    229     }
    230 
    231     public void benchmark(View v) {
    232         filter();
    233         long t = java.lang.System.currentTimeMillis();
    234         filter();
    235         t = java.lang.System.currentTimeMillis() - t;
    236         mDisplayView.invalidate();
    237         mBenchmarkResult.setText("Result: " + t + " ms");
    238     }
    239 }
    240