blob: 60d562bde8ce6dccdb809422a7457e5f5ecba7f7 [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.rs.image;
import android.app.Activity;
import android.os.Bundle;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.renderscript.ScriptC;
import android.renderscript.RenderScript;
import android.renderscript.Type;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.Script;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.widget.ImageView;
import android.widget.SeekBar;
import java.lang.Math;
public class ImageProcessingActivity extends Activity implements SurfaceHolder.Callback {
private Bitmap mBitmap;
private Params mParams;
private Script.Invokable mInvokable;
private int[] mInData;
private int[] mOutData;
@SuppressWarnings({"FieldCanBeLocal"})
private RenderScript mRS;
@SuppressWarnings({"FieldCanBeLocal"})
private Type mParamsType;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation mParamsAllocation;
@SuppressWarnings({"FieldCanBeLocal"})
private Type mPixelType;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation mInPixelsAllocation;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation mOutPixelsAllocation;
private SurfaceView mSurfaceView;
private ImageView mDisplayView;
static class Params {
public int inWidth;
public int outWidth;
public int inHeight;
public int outHeight;
public float threshold;
}
static class Pixel {
public byte a;
public byte r;
public byte g;
public byte b;
}
class FilterCallback extends RenderScript.RSMessage {
private Runnable mAction = new Runnable() {
public void run() {
mOutPixelsAllocation.readData(mOutData);
mBitmap.setPixels(mOutData, 0, mParams.outWidth, 0, 0,
mParams.outWidth, mParams.outHeight);
mDisplayView.invalidate();
}
};
@Override
public void run() {
mSurfaceView.removeCallbacks(mAction);
mSurfaceView.post(mAction);
}
}
private void javaFilter() {
long t = java.lang.System.currentTimeMillis();
int count = mParams.inWidth * mParams.inHeight;
float threshold = mParams.threshold * 255.f;
for (int i = 0; i < count; i++) {
final float r = (float)((mInData[i] >> 0) & 0xff);
final float g = (float)((mInData[i] >> 8) & 0xff);
final float b = (float)((mInData[i] >> 16) & 0xff);
final float luminance = 0.2125f * r +
0.7154f * g +
0.0721f * b;
if (luminance > threshold) {
mOutData[i] = mInData[i];
} else {
mOutData[i] = mInData[i] & 0xff000000;
}
}
t = java.lang.System.currentTimeMillis() - t;
android.util.Log.v("Img", "frame time ms " + t);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBitmap = loadBitmap(R.drawable.data);
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
mSurfaceView.getHolder().addCallback(this);
mDisplayView = (ImageView) findViewById(R.id.display);
mDisplayView.setImageBitmap(mBitmap);
((SeekBar) findViewById(R.id.threshold)).setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mParams.threshold = progress / 100.0f;
mParamsAllocation.data(mParams);
if (false) {
mInvokable.execute();
} else {
javaFilter();
mBitmap.setPixels(mOutData, 0, mParams.outWidth, 0, 0,
mParams.outWidth, mParams.outHeight);
mDisplayView.invalidate();
}
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
public void surfaceCreated(SurfaceHolder holder) {
mParams = createParams();
mInvokable = createScript();
mInvokable.execute();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
private Script.Invokable createScript() {
mRS = RenderScript.create();
mRS.mMessageCallback = new FilterCallback();
mParamsType = Type.createFromClass(mRS, Params.class, 1, "Parameters");
mParamsAllocation = Allocation.createTyped(mRS, mParamsType);
mParamsAllocation.data(mParams);
final int pixelCount = mParams.inWidth * mParams.inHeight;
mPixelType = Type.createFromClass(mRS, Pixel.class, 1, "Pixel");
mInPixelsAllocation = Allocation.createSized(mRS,
Element.createUser(mRS, Element.DataType.SIGNED_32),
pixelCount);
mOutPixelsAllocation = Allocation.createSized(mRS,
Element.createUser(mRS, Element.DataType.SIGNED_32),
pixelCount);
mInData = new int[pixelCount];
mBitmap.getPixels(mInData, 0, mParams.inWidth, 0, 0, mParams.inWidth, mParams.inHeight);
mInPixelsAllocation.data(mInData);
mOutData = new int[pixelCount];
mOutPixelsAllocation.data(mOutData);
ScriptC.Builder sb = new ScriptC.Builder(mRS);
sb.setType(mParamsType, "Params", 0);
sb.setType(mPixelType, "InPixel", 1);
sb.setType(mPixelType, "OutPixel", 2);
sb.setType(true, 2);
Script.Invokable invokable = sb.addInvokable("main");
sb.setScript(getResources(), R.raw.threshold);
//sb.setRoot(true);
ScriptC script = sb.create();
script.bindAllocation(mParamsAllocation, 0);
script.bindAllocation(mInPixelsAllocation, 1);
script.bindAllocation(mOutPixelsAllocation, 2);
return invokable;
}
private Params createParams() {
final Params params = new Params();
params.inWidth = params.outWidth = mBitmap.getWidth();
params.inHeight = params.outHeight = mBitmap.getHeight();
params.threshold = 0.5f;
return params;
}
private Bitmap loadBitmap(int resource) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return copyBitmap(BitmapFactory.decodeResource(getResources(), resource, options));
}
private static Bitmap copyBitmap(Bitmap source) {
Bitmap b = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
Canvas c = new Canvas(b);
c.drawBitmap(source, 0, 0, null);
source.recycle();
return b;
}
}