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 setLevels()59 private void setLevels() { 60 mInWMinInB = mInWhite - mInBlack; 61 mOutWMinOutB = mOutWhite - mOutBlack; 62 mOverInWMinInB = 1.f / mInWMinInB; 63 } 64 setSaturation()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 onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)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 onStartTrackingTouch(SeekBar seekBar)110 public void onStartTrackingTouch(SeekBar seekBar) { 111 } 112 onStopTrackingTouch(SeekBar seekBar)113 public void onStopTrackingTouch(SeekBar seekBar) { 114 } 115 116 @Override onCreate(Bundle savedInstanceState)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 loadBitmap(int resource)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 filter()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 benchmark(View v)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