I am using the following algorithm in Android Studio to equalize an image.
But it shows error in getRaster method and doesnot recognise it. Also getRGB is also showing errors.
Please tell me where I am going wrong.
I have edited the code as you said but it crashes.
import java.io.IOException;
import java.util.Arrays;
import java.lang.Object;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class webhist extends Activity {
Bitmap bi = null;
boolean isColored;
LinearLayout view;
LinearLayout view_color;
boolean flag;
private int SIZE = 256;
// Red, Green, Blue
private int NUMBER_OF_COLOURS = 3;
public final int RED = 0;
public final int GREEN = 1;
public final int BLUE = 2;
private int[][] colourBins;
private volatile boolean loaded = false;
private int maxY;
private static final int LDPI = 0;
private static final int MDPI = 1;
private static final int TVDPI = 2;
private static final int HDPI = 3;
private static final int XHDPI = 4;
float offset = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.activity_webhist);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
if(metrics.densityDpi==metrics.DENSITY_LOW)
offset = 0.75f;
else if(metrics.densityDpi==metrics.DENSITY_MEDIUM)
offset = 1f;
else if(metrics.densityDpi==metrics.DENSITY_TV)
offset = 1.33f;
else if(metrics.densityDpi==metrics.DENSITY_HIGH)
offset = 1.5f;
else if(metrics.densityDpi==metrics.DENSITY_XHIGH)
offset = 2f;
Log.e("NIRAV",""+offset);
colourBins = new int[NUMBER_OF_COLOURS][];
for (int i = 0; i < NUMBER_OF_COLOURS; i++) {
colourBins[i] = new int[SIZE];
}
loaded = false;
Button upload = (Button) findViewById(R.id.upload);
upload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (flag) {
view_color.removeAllViews();
view.removeAllViews();
}
Intent it = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(it, 101);
flag = true;
/*
* LinearLayout view = (LinearLayout) findViewById(R.id.lyt);
* view.addView(new MyHistogram(getApplicationContext()));
*/
}
});
Button histogram = (Button) findViewById(R.id.hst_btn);
histogram.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (bi != null) {
isColored = false;
view = (LinearLayout) findViewById(R.id.lyt);
view.addView(new MyHistogram(getApplicationContext(), bi));
}
}
});
Button histogram_color = (Button) findViewById(R.id.hst_color_btn);
histogram_color.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (bi != null) {
isColored = true;
view_color = (LinearLayout) findViewById(R.id.lyt_color);
view_color.addView(new MyHistogram(getApplicationContext(),
bi));
}
}
});
}
protected void onActivityResult(int requestCode, int resultCode,
Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch (requestCode) {
case 101:
if (resultCode == RESULT_OK) {
Uri selectedImage = imageReturnedIntent.getData();
String filename = getRealPathFromURI(selectedImage);
bi = BitmapFactory.decodeFile(filename);
/*
ByteArrayOutputStream out = new ByteArrayOutputStream();
bi.compress(Bitmap.CompressFormat.JPEG,10,out);
bi = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));*/
if(bi!=null)
{
try {
new MyAsync().execute();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public String getRealPathFromURI(Uri contentUri) {
Log.e("TEST", "GetRealPath : " + contentUri);
try {
if (contentUri.toString().contains("video")) {
String[] proj = { MediaStore.Video.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
class MyAsync extends AsyncTask
{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
showDialog(0);
}
@Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
try {
load(bi);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
ImageView img = (ImageView) findViewById(R.id.img);
img.setImageBitmap(bi);
((Button) findViewById(R.id.hst_btn)).setVisibility(View.VISIBLE);
((Button) findViewById(R.id.hst_color_btn)).setVisibility(View.VISIBLE);
dismissDialog(0);
}
}
public void load(Bitmap bi) throws IOException {
if (bi != null) {
// Reset all the bins
for (int i = 0; i < NUMBER_OF_COLOURS; i++) {
for (int j = 0; j < SIZE; j++) {
colourBins[i][j] = 0;
}
}
for (int x = 0; x < bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
int pixel = bi.getPixel(x, y);
colourBins[RED][Color.red(pixel)]++;
colourBins[GREEN][Color.green(pixel)]++;
colourBins[BLUE][Color.blue(pixel)]++;
}
}
maxY = 0;
for (int i = 0; i < NUMBER_OF_COLOURS; i++) {
for (int j = 0; j < SIZE; j++) {
if (maxY < colourBins[i][j]) {
maxY = colourBins[i][j];
}
}
}
loaded = true;
} else {
loaded = false;
}
}
class MyHistogram extends View {
public MyHistogram(Context context, Bitmap bi) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
if (loaded) {
canvas.drawColor(Color.GRAY);
Log.e("NIRAV", "Height : " + getHeight() + ", Width : "
+ getWidth());
int xInterval = (int) ((double) getWidth() / ((double) SIZE + 1));
for (int i = 0; i < NUMBER_OF_COLOURS; i++) {
Paint wallpaint;
wallpaint = new Paint();
if (isColored) {
if (i == RED) {
wallpaint.setColor(Color.RED);
} else if (i == GREEN) {
wallpaint.setColor(Color.GREEN);
} else if (i == BLUE) {
wallpaint.setColor(Color.BLUE);
}
} else {
wallpaint.setColor(Color.WHITE);
}
wallpaint.setStyle(Style.FILL);
Path wallpath = new Path();
wallpath.reset();
wallpath.moveTo(0, getHeight());
for (int j = 0; j < SIZE - 1; j++) {
int value = (int) (((double) colourBins[i][j] / (double) maxY) * (getHeight()+100));
//if(j==0) {
// wallpath.moveTo(j * xInterval* offset, getHeight() - value);
//}
// else {
wallpath.lineTo(j * xInterval * offset, getHeight() - value);
// }
}
wallpath.lineTo(SIZE * offset, getHeight());
canvas.drawPath(wallpath, wallpaint);
}
}
}
}
public void gray(View view1) {
operation = Bitmap.createBitmap(bi.getWidth(),
bi.getHeight(), bi.getConfig());
histEqualize(bi,operation);
}
public int[] CalculateHist(Bitmap bi) {
int k;
//array represents the intecity values of the pixels
int levels[] = new int[256];
for (int i = 0; i < bi.getWidth(); i++) {
for (int j = 0; j < bi.getHeight(); j++) {
int pixel = bi.getPixel(i, j);
//increase if same pixel appears
levels[Color.red(pixel)]++;
}
}
//return the histogram array
return levels;
}
public void histEqualize(Bitmap bi, Bitmap bi_out) {
//call CalculateHist method to get the histogram
int[] h = CalculateHist(bi);
//calculate total number of pixel
int mass = bi.getWidth() * bi.getHeight();
int k = 0;
long sum = 0;
//calculate the scale factor
float scale = (float) 255.0 / mass;
//calculte cdf
for (int x = 0; x < h.length; x++) {
sum += h[x];
int value = (int) (scale * sum);
if (value > 255) {
value = 255;
}
h[x] = value;
}
for (int i = 0; i < bi.getWidth(); i++) {
for (int j = 0; j < bi.getHeight(); j++) {
int pixel = bi.getPixel(i, j);
//set the new value
k = h[Color.red(pixel)];
int rgb = Color.rgb(k, k, k);
bi_out.setPixel(i, j, rgb);
}
}
}
// int pixel[];
@Override
protected Dialog onCreateDialog(int id) {
ProgressDialog dataLoadProgress = new ProgressDialog(this);
dataLoadProgress.setMessage("Loading...");
dataLoadProgress.setIndeterminate(true);
dataLoadProgress.setCancelable(false);
dataLoadProgress.setProgressStyle(android.R.attr.progressBarStyleLarge);
return dataLoadProgress;
}
}
This is My layout.xml file
android:layout_width="match_parent"
android:layout_height="match_parent">
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/holo_blue_bright">
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical"
android:background="@android:color/white">
android:id="@+id/lyt"
android:layout_width="383dp"
android:layout_height="140dp"
android:orientation="vertical" >
android:id="@+id/hst_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Histogram"
android:visibility="invisible"/>
android:id="@+id/hst_color_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Color Histogram"
android:visibility="invisible"/>
android:id="@+id/lyt_color"
android:layout_width="match_parent"
android:layout_height="140dp"
android:orientation="vertical" >
android:layout_width="match_parent"
android:layout_height="267dp" >
android:id="@+id/img"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
/>
android:layout_height="wrap_content"
android:text="Select Image"
android:id="@+id/upload"
android:layout_margin="20dp"
android:background="@android:color/white"
android:textColor="@android:color/black"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Equalised image"
android:onClick="gray"
android:id="@+id/button"
android:layout_alignTop="@+id/upload"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="38dp"
android:layout_marginEnd="38dp" />
android:id="@+id/imageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter"
android:layout_alignParentEnd="false" />
解决方案
There is no getRaster() method in the Android Bitmap class. Instead you can call getPixel() on the Bitmap directly. The function returns an integer ARGB value, which you can separate into its various components:
int pixel = bi.getPixel(i, j);
//increase if same pixel appears
levels[Color.red(pixel)]++;
You can set a pixel like this:
int rgb = Color.rgb(k, k, k);
bi.setPixel(i, j, rgb);