Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2009 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.image; |
| 18 | |
| 19 | import android.app.Activity; |
| 20 | import android.os.Bundle; |
| 21 | import android.graphics.BitmapFactory; |
| 22 | import android.graphics.Bitmap; |
| 23 | import android.graphics.Canvas; |
| 24 | import android.renderscript.ScriptC; |
| 25 | import android.renderscript.RenderScript; |
| 26 | import android.renderscript.Type; |
| 27 | import android.renderscript.Allocation; |
| 28 | import android.renderscript.Element; |
| 29 | import android.renderscript.Script; |
| 30 | import android.view.SurfaceView; |
| 31 | import android.view.SurfaceHolder; |
| 32 | import android.widget.ImageView; |
| 33 | import android.widget.SeekBar; |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 34 | import android.widget.TextView; |
| 35 | import android.view.View; |
Jason Sams | 586f3b5 | 2010-02-10 18:07:37 -0800 | [diff] [blame] | 36 | import java.lang.Math; |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 37 | |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 38 | public class ImageProcessingActivity extends Activity |
| 39 | implements SurfaceHolder.Callback, |
| 40 | SeekBar.OnSeekBarChangeListener { |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 41 | private Bitmap mBitmapIn; |
| 42 | private Bitmap mBitmapOut; |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 43 | private Bitmap mBitmapScratch; |
Stephen Hines | 93a958f | 2010-09-16 17:18:55 -0700 | [diff] [blame] | 44 | private ScriptC_threshold mScript; |
| 45 | private ScriptC_vertical_blur mScriptVBlur; |
| 46 | private ScriptC_horizontal_blur mScriptHBlur; |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 47 | private int mRadius = 0; |
| 48 | private SeekBar mRadiusSeekBar; |
| 49 | |
| 50 | private float mInBlack = 0.0f; |
| 51 | private SeekBar mInBlackSeekBar; |
| 52 | private float mOutBlack = 0.0f; |
| 53 | private SeekBar mOutBlackSeekBar; |
| 54 | private float mInWhite = 255.0f; |
| 55 | private SeekBar mInWhiteSeekBar; |
| 56 | private float mOutWhite = 255.0f; |
| 57 | private SeekBar mOutWhiteSeekBar; |
| 58 | private float mGamma = 1.0f; |
| 59 | private SeekBar mGammaSeekBar; |
| 60 | |
| 61 | private float mSaturation = 1.0f; |
| 62 | private SeekBar mSaturationSeekBar; |
| 63 | |
| 64 | private TextView mBenchmarkResult; |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 65 | |
| 66 | @SuppressWarnings({"FieldCanBeLocal"}) |
| 67 | private RenderScript mRS; |
| 68 | @SuppressWarnings({"FieldCanBeLocal"}) |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 69 | private Type mPixelType; |
| 70 | @SuppressWarnings({"FieldCanBeLocal"}) |
| 71 | private Allocation mInPixelsAllocation; |
| 72 | @SuppressWarnings({"FieldCanBeLocal"}) |
| 73 | private Allocation mOutPixelsAllocation; |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 74 | @SuppressWarnings({"FieldCanBeLocal"}) |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 75 | private Allocation mScratchPixelsAllocation1; |
| 76 | private Allocation mScratchPixelsAllocation2; |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 77 | |
| 78 | private SurfaceView mSurfaceView; |
| 79 | private ImageView mDisplayView; |
| 80 | |
Jason Sams | bf6ef8d | 2010-12-06 15:59:59 -0800 | [diff] [blame] | 81 | class FilterCallback extends RenderScript.RSMessageHandler { |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 82 | private Runnable mAction = new Runnable() { |
| 83 | public void run() { |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 84 | mDisplayView.invalidate(); |
| 85 | } |
Jason Sams | 718cd1f | 2009-12-23 14:35:29 -0800 | [diff] [blame] | 86 | }; |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 87 | |
| 88 | @Override |
| 89 | public void run() { |
| 90 | mSurfaceView.removeCallbacks(mAction); |
| 91 | mSurfaceView.post(mAction); |
| 92 | } |
| 93 | } |
| 94 | |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 95 | int in[]; |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 96 | int interm[]; |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 97 | int out[]; |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 98 | int MAX_RADIUS = 25; |
| 99 | // Store our coefficients here |
| 100 | float gaussian[]; |
| 101 | |
| 102 | private long javaFilter() { |
| 103 | final int width = mBitmapIn.getWidth(); |
| 104 | final int height = mBitmapIn.getHeight(); |
| 105 | final int count = width * height; |
Jason Sams | 586f3b5 | 2010-02-10 18:07:37 -0800 | [diff] [blame] | 106 | |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 107 | if (in == null) { |
| 108 | in = new int[count]; |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 109 | interm = new int[count]; |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 110 | out = new int[count]; |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 111 | gaussian = new float[MAX_RADIUS * 2 + 1]; |
| 112 | mBitmapIn.getPixels(in, 0, width, 0, 0, width, height); |
Jason Sams | 586f3b5 | 2010-02-10 18:07:37 -0800 | [diff] [blame] | 113 | } |
| 114 | |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 115 | long t = java.lang.System.currentTimeMillis(); |
Jason Sams | 586f3b5 | 2010-02-10 18:07:37 -0800 | [diff] [blame] | 116 | |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 117 | int w, h, r; |
| 118 | |
| 119 | float fRadius = (float)mRadius; |
| 120 | int radius = (int)mRadius; |
| 121 | |
| 122 | // Compute gaussian weights for the blur |
| 123 | // e is the euler's number |
| 124 | float e = 2.718281828459045f; |
| 125 | float pi = 3.1415926535897932f; |
| 126 | // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 ) |
| 127 | // x is of the form [-radius .. 0 .. radius] |
| 128 | // and sigma varies with radius. |
| 129 | // Based on some experimental radius values and sigma's |
| 130 | // we approximately fit sigma = f(radius) as |
| 131 | // sigma = radius * 0.4 + 0.6 |
| 132 | // The larger the radius gets, the more our gaussian blur |
| 133 | // will resemble a box blur since with large sigma |
| 134 | // the gaussian curve begins to lose its shape |
| 135 | float sigma = 0.4f * fRadius + 0.6f; |
| 136 | // Now compute the coefficints |
| 137 | // We will store some redundant values to save some math during |
| 138 | // the blur calculations |
| 139 | // precompute some values |
| 140 | float coeff1 = 1.0f / (float)(Math.sqrt( 2.0f * pi ) * sigma); |
| 141 | float coeff2 = - 1.0f / (2.0f * sigma * sigma); |
| 142 | float normalizeFactor = 0.0f; |
| 143 | float floatR = 0.0f; |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 144 | for (r = -radius; r <= radius; r ++) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 145 | floatR = (float)r; |
| 146 | gaussian[r + radius] = coeff1 * (float)Math.pow(e, floatR * floatR * coeff2); |
| 147 | normalizeFactor += gaussian[r + radius]; |
| 148 | } |
| 149 | |
| 150 | //Now we need to normalize the weights because all our coefficients need to add up to one |
| 151 | normalizeFactor = 1.0f / normalizeFactor; |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 152 | for (r = -radius; r <= radius; r ++) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 153 | floatR = (float)r; |
| 154 | gaussian[r + radius] *= normalizeFactor; |
| 155 | } |
| 156 | |
| 157 | float blurredPixelR = 0.0f; |
| 158 | float blurredPixelG = 0.0f; |
| 159 | float blurredPixelB = 0.0f; |
| 160 | float blurredPixelA = 0.0f; |
| 161 | |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 162 | for (h = 0; h < height; h ++) { |
| 163 | for (w = 0; w < width; w ++) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 164 | |
| 165 | blurredPixelR = 0.0f; |
| 166 | blurredPixelG = 0.0f; |
| 167 | blurredPixelB = 0.0f; |
| 168 | blurredPixelA = 0.0f; |
| 169 | |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 170 | for (r = -radius; r <= radius; r ++) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 171 | // Stepping left and right away from the pixel |
| 172 | int validW = w + r; |
| 173 | // Clamp to zero and width max() isn't exposed for ints yet |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 174 | if (validW < 0) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 175 | validW = 0; |
| 176 | } |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 177 | if (validW > width - 1) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 178 | validW = width - 1; |
| 179 | } |
| 180 | |
| 181 | int input = in[h*width + validW]; |
| 182 | |
| 183 | int R = ((input >> 24) & 0xff); |
| 184 | int G = ((input >> 16) & 0xff); |
| 185 | int B = ((input >> 8) & 0xff); |
| 186 | int A = (input & 0xff); |
| 187 | |
| 188 | float weight = gaussian[r + radius]; |
| 189 | |
| 190 | blurredPixelR += (float)(R)*weight; |
| 191 | blurredPixelG += (float)(G)*weight; |
| 192 | blurredPixelB += (float)(B)*weight; |
| 193 | blurredPixelA += (float)(A)*weight; |
| 194 | } |
| 195 | |
| 196 | int R = (int)blurredPixelR; |
| 197 | int G = (int)blurredPixelG; |
| 198 | int B = (int)blurredPixelB; |
| 199 | int A = (int)blurredPixelA; |
| 200 | |
| 201 | interm[h*width + w] = (R << 24) | (G << 16) | (B << 8) | (A); |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 202 | } |
| 203 | } |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 204 | |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 205 | for (h = 0; h < height; h ++) { |
| 206 | for (w = 0; w < width; w ++) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 207 | |
| 208 | blurredPixelR = 0.0f; |
| 209 | blurredPixelG = 0.0f; |
| 210 | blurredPixelB = 0.0f; |
| 211 | blurredPixelA = 0.0f; |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 212 | for (r = -radius; r <= radius; r ++) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 213 | int validH = h + r; |
| 214 | // Clamp to zero and width |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 215 | if (validH < 0) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 216 | validH = 0; |
| 217 | } |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 218 | if (validH > height - 1) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 219 | validH = height - 1; |
| 220 | } |
| 221 | |
| 222 | int input = interm[validH*width + w]; |
| 223 | |
| 224 | int R = ((input >> 24) & 0xff); |
| 225 | int G = ((input >> 16) & 0xff); |
| 226 | int B = ((input >> 8) & 0xff); |
| 227 | int A = (input & 0xff); |
| 228 | |
| 229 | float weight = gaussian[r + radius]; |
| 230 | |
| 231 | blurredPixelR += (float)(R)*weight; |
| 232 | blurredPixelG += (float)(G)*weight; |
| 233 | blurredPixelB += (float)(B)*weight; |
| 234 | blurredPixelA += (float)(A)*weight; |
| 235 | } |
| 236 | |
| 237 | int R = (int)blurredPixelR; |
| 238 | int G = (int)blurredPixelG; |
| 239 | int B = (int)blurredPixelB; |
| 240 | int A = (int)blurredPixelA; |
| 241 | |
| 242 | out[h*width + w] = (R << 24) | (G << 16) | (B << 8) | (A); |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | t = java.lang.System.currentTimeMillis() - t; |
| 247 | android.util.Log.v("Img", "Java frame time ms " + t); |
| 248 | mBitmapOut.setPixels(out, 0, width, 0, 0, width, height); |
| 249 | return t; |
| 250 | } |
| 251 | |
| 252 | public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { |
| 253 | if (fromUser) { |
| 254 | |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 255 | if (seekBar == mRadiusSeekBar) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 256 | float fRadius = progress / 100.0f; |
| 257 | fRadius *= (float)(MAX_RADIUS); |
| 258 | mRadius = (int)fRadius; |
| 259 | |
| 260 | mScript.set_radius(mRadius); |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 261 | } else if (seekBar == mInBlackSeekBar) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 262 | mInBlack = (float)progress; |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 263 | mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 264 | } else if (seekBar == mOutBlackSeekBar) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 265 | mOutBlack = (float)progress; |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 266 | mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 267 | } else if (seekBar == mInWhiteSeekBar) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 268 | mInWhite = (float)progress + 127.0f; |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 269 | mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 270 | } else if (seekBar == mOutWhiteSeekBar) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 271 | mOutWhite = (float)progress + 127.0f; |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 272 | mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 273 | } else if (seekBar == mGammaSeekBar) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 274 | mGamma = (float)progress/100.0f; |
| 275 | mGamma = Math.max(mGamma, 0.1f); |
| 276 | mGamma = 1.0f / mGamma; |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 277 | mScriptVBlur.invoke_setGamma(mGamma); |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 278 | } else if (seekBar == mSaturationSeekBar) { |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 279 | mSaturation = (float)progress / 50.0f; |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 280 | mScriptVBlur.invoke_setSaturation(mSaturation); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 281 | } |
| 282 | |
| 283 | long t = java.lang.System.currentTimeMillis(); |
| 284 | if (true) { |
Jason Sams | f110d4b | 2010-06-21 17:42:41 -0700 | [diff] [blame] | 285 | mScript.invoke_filter(); |
Jason Sams | 4ef6650 | 2010-12-10 16:03:15 -0800 | [diff] [blame] | 286 | mOutPixelsAllocation.copyTo(mBitmapOut); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 287 | } else { |
| 288 | javaFilter(); |
Jason Sams | f0690c4 | 2010-07-29 17:31:14 -0700 | [diff] [blame] | 289 | mDisplayView.invalidate(); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 290 | } |
| 291 | |
| 292 | t = java.lang.System.currentTimeMillis() - t; |
| 293 | android.util.Log.v("Img", "Renderscript frame time core ms " + t); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 294 | } |
| 295 | } |
| 296 | |
| 297 | public void onStartTrackingTouch(SeekBar seekBar) { |
| 298 | } |
| 299 | |
| 300 | public void onStopTrackingTouch(SeekBar seekBar) { |
Jason Sams | 586f3b5 | 2010-02-10 18:07:37 -0800 | [diff] [blame] | 301 | } |
| 302 | |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 303 | @Override |
| 304 | protected void onCreate(Bundle savedInstanceState) { |
| 305 | super.onCreate(savedInstanceState); |
| 306 | setContentView(R.layout.main); |
| 307 | |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 308 | mBitmapIn = loadBitmap(R.drawable.data); |
| 309 | mBitmapOut = loadBitmap(R.drawable.data); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 310 | mBitmapScratch = loadBitmap(R.drawable.data); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 311 | |
| 312 | mSurfaceView = (SurfaceView) findViewById(R.id.surface); |
| 313 | mSurfaceView.getHolder().addCallback(this); |
| 314 | |
| 315 | mDisplayView = (ImageView) findViewById(R.id.display); |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 316 | mDisplayView.setImageBitmap(mBitmapOut); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 317 | |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 318 | mRadiusSeekBar = (SeekBar) findViewById(R.id.radius); |
| 319 | mRadiusSeekBar.setOnSeekBarChangeListener(this); |
Jason Sams | 586f3b5 | 2010-02-10 18:07:37 -0800 | [diff] [blame] | 320 | |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 321 | mInBlackSeekBar = (SeekBar)findViewById(R.id.inBlack); |
| 322 | mInBlackSeekBar.setOnSeekBarChangeListener(this); |
| 323 | mInBlackSeekBar.setMax(128); |
| 324 | mInBlackSeekBar.setProgress(0); |
| 325 | mOutBlackSeekBar = (SeekBar)findViewById(R.id.outBlack); |
| 326 | mOutBlackSeekBar.setOnSeekBarChangeListener(this); |
| 327 | mOutBlackSeekBar.setMax(128); |
| 328 | mOutBlackSeekBar.setProgress(0); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 329 | |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 330 | mInWhiteSeekBar = (SeekBar)findViewById(R.id.inWhite); |
| 331 | mInWhiteSeekBar.setOnSeekBarChangeListener(this); |
| 332 | mInWhiteSeekBar.setMax(128); |
| 333 | mInWhiteSeekBar.setProgress(128); |
| 334 | mOutWhiteSeekBar = (SeekBar)findViewById(R.id.outWhite); |
| 335 | mOutWhiteSeekBar.setOnSeekBarChangeListener(this); |
| 336 | mOutWhiteSeekBar.setMax(128); |
| 337 | mOutWhiteSeekBar.setProgress(128); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 338 | |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 339 | mGammaSeekBar = (SeekBar)findViewById(R.id.inGamma); |
| 340 | mGammaSeekBar.setOnSeekBarChangeListener(this); |
| 341 | mGammaSeekBar.setMax(150); |
| 342 | mGammaSeekBar.setProgress(100); |
| 343 | |
| 344 | mSaturationSeekBar = (SeekBar)findViewById(R.id.inSaturation); |
| 345 | mSaturationSeekBar.setOnSeekBarChangeListener(this); |
| 346 | mSaturationSeekBar.setProgress(50); |
| 347 | |
| 348 | mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText); |
Alex Sakhartchouk | db217e0 | 2011-02-17 14:43:27 -0800 | [diff] [blame] | 349 | mBenchmarkResult.setText("Result: not run"); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 350 | } |
| 351 | |
| 352 | public void surfaceCreated(SurfaceHolder holder) { |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 353 | createScript(); |
Jason Sams | f110d4b | 2010-06-21 17:42:41 -0700 | [diff] [blame] | 354 | mScript.invoke_filter(); |
Jason Sams | 4ef6650 | 2010-12-10 16:03:15 -0800 | [diff] [blame] | 355 | mOutPixelsAllocation.copyTo(mBitmapOut); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 356 | } |
| 357 | |
| 358 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { |
| 359 | } |
| 360 | |
| 361 | public void surfaceDestroyed(SurfaceHolder holder) { |
| 362 | } |
Jason Sams | 718cd1f | 2009-12-23 14:35:29 -0800 | [diff] [blame] | 363 | |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 364 | private void createScript() { |
Shih-wei Liao | 6b32fab | 2010-12-10 01:03:59 -0800 | [diff] [blame] | 365 | mRS = RenderScript.create(this); |
Jason Sams | bf6ef8d | 2010-12-06 15:59:59 -0800 | [diff] [blame] | 366 | mRS.setMessageHandler(new FilterCallback()); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 367 | |
Jason Sams | 4ef6650 | 2010-12-10 16:03:15 -0800 | [diff] [blame] | 368 | mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn, |
| 369 | Allocation.MipmapControl.MIPMAP_NONE, |
| 370 | Allocation.USAGE_SCRIPT); |
| 371 | mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut, |
| 372 | Allocation.MipmapControl.MIPMAP_NONE, |
| 373 | Allocation.USAGE_SCRIPT); |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 374 | |
| 375 | Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS)); |
Jason Sams | bf6ef8d | 2010-12-06 15:59:59 -0800 | [diff] [blame] | 376 | tb.setX(mBitmapIn.getWidth()); |
| 377 | tb.setY(mBitmapIn.getHeight()); |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 378 | mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create()); |
| 379 | mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create()); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 380 | |
Jason Sams | 3ba02b3 | 2010-11-03 23:01:38 -0700 | [diff] [blame] | 381 | mScriptVBlur = new ScriptC_vertical_blur(mRS, getResources(), R.raw.vertical_blur); |
| 382 | mScriptHBlur = new ScriptC_horizontal_blur(mRS, getResources(), R.raw.horizontal_blur); |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 383 | |
Jason Sams | 3ba02b3 | 2010-11-03 23:01:38 -0700 | [diff] [blame] | 384 | mScript = new ScriptC_threshold(mRS, getResources(), R.raw.threshold); |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 385 | mScript.set_width(mBitmapIn.getWidth()); |
| 386 | mScript.set_height(mBitmapIn.getHeight()); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 387 | mScript.set_radius(mRadius); |
| 388 | |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 389 | mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); |
| 390 | mScriptVBlur.invoke_setGamma(mGamma); |
| 391 | mScriptVBlur.invoke_setSaturation(mSaturation); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 392 | |
Jason Sams | 4d33993 | 2010-05-11 14:03:58 -0700 | [diff] [blame] | 393 | mScript.bind_InPixel(mInPixelsAllocation); |
| 394 | mScript.bind_OutPixel(mOutPixelsAllocation); |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 395 | mScript.bind_ScratchPixel1(mScratchPixelsAllocation1); |
| 396 | mScript.bind_ScratchPixel2(mScratchPixelsAllocation2); |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 397 | |
| 398 | mScript.set_vBlurScript(mScriptVBlur); |
| 399 | mScript.set_hBlurScript(mScriptHBlur); |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 400 | } |
| 401 | |
| 402 | private Bitmap loadBitmap(int resource) { |
| 403 | final BitmapFactory.Options options = new BitmapFactory.Options(); |
| 404 | options.inPreferredConfig = Bitmap.Config.ARGB_8888; |
| 405 | return copyBitmap(BitmapFactory.decodeResource(getResources(), resource, options)); |
| 406 | } |
| 407 | |
| 408 | private static Bitmap copyBitmap(Bitmap source) { |
| 409 | Bitmap b = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig()); |
| 410 | Canvas c = new Canvas(b); |
| 411 | c.drawBitmap(source, 0, 0, null); |
| 412 | source.recycle(); |
| 413 | return b; |
| 414 | } |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 415 | |
| 416 | // button hook |
| 417 | public void benchmark(View v) { |
| 418 | android.util.Log.v("Img", "Benchmarking"); |
| 419 | int oldRadius = mRadius; |
| 420 | mRadius = MAX_RADIUS; |
| 421 | mScript.set_radius(mRadius); |
| 422 | |
| 423 | long t = java.lang.System.currentTimeMillis(); |
| 424 | |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 425 | mScript.invoke_filter(); |
Jason Sams | 4ef6650 | 2010-12-10 16:03:15 -0800 | [diff] [blame] | 426 | mOutPixelsAllocation.copyTo(mBitmapOut); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 427 | |
| 428 | t = java.lang.System.currentTimeMillis() - t; |
| 429 | android.util.Log.v("Img", "Renderscript frame time core ms " + t); |
| 430 | |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 431 | //long javaTime = javaFilter(); |
| 432 | //mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms"); |
Alex Sakhartchouk | db217e0 | 2011-02-17 14:43:27 -0800 | [diff] [blame] | 433 | mBenchmarkResult.setText("Result: " + t + " ms"); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 434 | |
| 435 | mRadius = oldRadius; |
| 436 | mScript.set_radius(mRadius); |
| 437 | |
Jason Sams | f110d4b | 2010-06-21 17:42:41 -0700 | [diff] [blame] | 438 | mScript.invoke_filter(); |
Jason Sams | 4ef6650 | 2010-12-10 16:03:15 -0800 | [diff] [blame] | 439 | mOutPixelsAllocation.copyTo(mBitmapOut); |
Alex Sakhartchouk | 814326b | 2010-05-19 16:28:27 -0700 | [diff] [blame] | 440 | } |
Romain Guy | d7fa122 | 2009-10-09 16:05:25 -0700 | [diff] [blame] | 441 | } |