I am trying to display a bitmap image pixel by pixel (which explicitly means with some delay).
For that I am using two "for-loops", but it prints only a single row of pixels...
My code:
Button start = (Button) findViewById(R.id.start);
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(getBaseContext(), "Printing...", Toast.LENGTH_SHORT).show();
iImageArray = new int[bMap.getWidth()* bMap.getHeight()]; //initializing the array for the image size
bMap.getPixels(iImageArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight()); //copy pixel data from the Bitmap into the 'intArray' array
//Canvas canvas = new Canvas (bMap);
//replace the red pixels with yellow ones
for (int i=0; i < bMap.getHeight(); i++) {
for(int j=0; j<bMap.getWidth(); j++) {
iImageArray[j] = 0xFFFFFFFF;
}
}
bMap = Bitmap.createBitmap(iImageArray, bMap.getWidth(), bMap.getHeight(), Bitmap.Config.ARGB_8888);//Initialize the bitmap, with the replaced color
image.setImageBitmap(bMap);
//canvas.drawPoints(iImageArray, 0, bMap.getHeight()*bMap.getWidth(), paint);
}
});
And I want to print the bitmap in grayscale and for that I found this code...
public Bitmap toGrayscale(Bitmap bmpOriginal) {
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}
It is iImageArray[i] = 0xFFFFFFFF; that I have to test, not the actual grayscale value...
Your code looks basically correct except for your inner loop. Your comment says that you're setting them to yellow, but you're actually storing white. The loop will only affect the first row of pixels because your array index has a range of 0 to width-1. You can either calculate the index by multiplying (i*width+j) or keep a counter that increments.
Original Version:
//replace the red pixels with yellow ones
for (int i=0; i < bMap.getHeight(); i++)
{
for(int j=0; j<bMap.getWidth(); j++)
{
iImageArray[j] = 0xFFFFFFFF;
}
}
Fixed Version:
//replace the red pixels with yellow ones
int iWidth = bMap.getWidth();
for (int i=0; i < bMap.getHeight(); i++)
{
for(int j=0; j<bMap.getWidth(); j++)
{
iImageArray[(i*iWidth)+j] = 0xFF00FFFF; // actual value of yellow
}
}
I also made a program that reads the RGB colors of every pixels from an image.
Here is my code to read:
int orgWidth = bmp.getWidth();
int orgHeight = bmp.getHeight();
//define the array size
int[] pixels = new int[orgWidth * orgHeight];
bmp.getPixels(pixels, 0, orgWidth, 0, 0, orgWidth, orgHeight);
for (int y = 0; y < orgHeight; y++){
for (int x = 0; x < orgWidth; x++){
}
}
This is how my array works.
I made a question for ranged pixel check last week, however I also fixed it by my self :)
Optimize Color range check with nested for loop
EDIT:
Now I see, sorry.
at: iImageArray[j] = 0xFFFFFFFF;
also add iImageArray[i] = 0xFFFFFFFF;
then it should work
Related
I'm trying to write a cellular automata program that manipulates integer values in an array and then displays the array as an image.
array of integers --> image --> display on screen
I've tried BitmapFactory.decodeByteArray(), and Bitmap.createBitmap() but all the examples require reading an existing .jpg or .png into a byte[], which is then converted back into a bitmap.
Does anyone have a clear example of building an array from scratch, converting to an image and then displaying? Even the simplest example of an entirely blue square 50x50 pixels would be helpful.
If BitmapFactory.decodeByteArray() is not the best option, I'm open to any alternatives.
Thanks!
my code so far, from an onClick() method:
display = (ImageView) findViewById(R.id.imageView1);
Bitmap bMap = null;
int w = 50, h = 50; // set width = height = 50
byte[] input = new byte[w * h]; // initialize input array
for (int y = 0; y < h; y++) { // fill input with blue
for (int x = 0; x < w; x++) {
input[y * w + x] = (byte) Color.BLUE;
}
}
bMap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, Bitmap.Config.ARGB_8888); // convert byte array to bitmap
display.setImageBitmap(bMap); // post bitmap to imageview
// You are using RGBA that's why Config is ARGB.8888
bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
// vector is your int[] of ARGB value .
bitmap.copyPixelsFromBuffer(makeBuffer(vector, vector.length));
private IntBuffer makeBuffer(int[] src, int n) {
IntBuffer dst = IntBuffer.allocate(n*n);
for (int i = 0; i < n; i++) {
dst.put(src);
}
dst.rewind();
return dst;
}
creating an empty bitmap and drawing though canvas in android
I am new to Android and need to process a bitmap to extract the pixel information into a multi-dimensional array by collecting only the black pixels i.e. R = 0, G = 0, and B = 0. I noticed that there is a GetPixel(x, y) method which is apparently slow and I need something like this instead. But I'm lost on how to implement a better GetPixel(x, y) method using information from GetPixels(). I am trying something like this currently:
private static int[][] GetPixels(Bitmap bmp)
{
int height = bmp.getHeight();
int width = bmp.getWidth();
int length = width * height;
int[] pixels = new int[length];
bmp.getPixels(pixels, 0, 0, 0, 0, width, height);
int[][]result = new int[width][height];
for(int pixel = 0, x = 0, y = 0; pixel < pixels.length; pixel += 4)
{
int argb = pixels[pixel];//how to access pixel information?
result[x][y] = argb;//store only black pixels??
x++;
if(y == width)
{
x = 0;
y++;
}
}
return result;
}
I have images which I display in my app. They are downloaded from the web. These images are pictures of objects on an almost-white background. I want this background to be white (#FFFFFF). I figure, if I look at pixel 0,0 (which should always be off-white), I can get the color value and replace every pixel in the image having that value with white.
This question has been asked before and the answer seems to be this:
int intOldColor = bmpOldBitmap.getPixel(0,0);
Bitmap bmpNewBitmap = Bitmap.createBitmap(bmpOldBitmap.getWidth(), bmpOldBitmap.getHeight(), Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpNewBitmap);
Paint paint = new Paint();
ColorFilter filter = new LightingColorFilter(intOldColor, Color.WHITE);
paint.setColorFilter(filter);
c.drawBitmap(bmpOriginal, 0, 0, paint);
However, this isn't working.
After running this code, the entire image seems to be the color I was wanting to remove. As in, the entire image is 1 solid color now.
I was also hoping to not have to loop through every pixel in the entire image.
Any ideas?
Here is a method I created for you to replace a specific color for the one you want. Note that all the pixels will get scanned on the Bitmap and only the ones that are equal will be replaced for the one you want.
private Bitmap changeColor(Bitmap src, int colorToReplace, int colorThatWillReplace) {
int width = src.getWidth();
int height = src.getHeight();
int[] pixels = new int[width * height];
// get pixel array from source
src.getPixels(pixels, 0, width, 0, 0, width, height);
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
int A, R, G, B;
int pixel;
// iteration through pixels
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
// get current index in 2D-matrix
int index = y * width + x;
pixel = pixels[index];
if(pixel == colorToReplace){
//change A-RGB individually
A = Color.alpha(colorThatWillReplace);
R = Color.red(colorThatWillReplace);
G = Color.green(colorThatWillReplace);
B = Color.blue(colorThatWillReplace);
pixels[index] = Color.argb(A,R,G,B);
/*or change the whole color
pixels[index] = colorThatWillReplace;*/
}
}
}
bmOut.setPixels(pixels, 0, width, 0, 0, width, height);
return bmOut;
}
I hope that helped :)
I am trying to add snow flow effect. but not succeed
I tried to do the effect of continuously flow the snow.
is it possible? if yes than please give suggestion.
my code is below.
public class MainActivity extends Activity {
private int COLOR_MAX = 0xff;
ImageView image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView)findViewById(R.id.imageView1);
Bitmap imagebitmap = BitmapFactory.decodeResource(getResources(),R.drawable.hydrangeas);
applySnowEffect(imagebitmap);
}
Bitmap applySnowEffect(Bitmap source)
{
// get image size
int width = source.getWidth();
int height = source.getHeight();
int[] pixels = new int[width * height];
// get pixel array from source
source.getPixels(pixels, 0, width, 0, 0, width, height);
// random object
Random random = new Random();
int R, G, B, index = 0, thresHold = 50;
// iteration through pixels
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
// get current index in 2D-matrix
index = y * width + x;
// get color
R = Color.red(pixels[index]);
G = Color.green(pixels[index]);
B = Color.blue(pixels[index]);
// generate threshold
thresHold = random.nextInt(COLOR_MAX );
if(R > thresHold && G > thresHold && B > thresHold) {
pixels[index] = Color.rgb(COLOR_MAX, COLOR_MAX, COLOR_MAX);
}
}
}
// output bitmap
Bitmap bmOut = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
bmOut.setPixels(pixels, 0, width, 0, 0, width, height);
Toast.makeText(getApplicationContext(),"processed",10).show();
return bmOut;
}
I actually read about this the other day. You can use a particle system for Android. A library that can assist with that is found here - https://github.com/plattysoft/Leonids
Well I've just find the solution.
The source is here: code link
The main idea is SnowFallView extends View, and overriding onDraw(Canvas canvas) event, where we drawing our snow flakes drawables.
The code is just tested and works well.
I've got a Bitmap with some transparent pixels and rest is mainly black (some black pixels possibly have a few sem-transparent pixels).
I need to re-use these bitmaps and want to be able to essentially create a Mask out of this bitmap at runtime and then try and blend with a block of another color (like Red, green etc) so that the end result is the same image but with red color (and those pixels which were semi-transparent black pixels turn into semi-transparent red pixels).
I've tried all sorts of color filters and xfermodes but have not been able to figure out. Please help!
If you doesn't need high speed, you can use simple solution by manually blend pixels.
final Bitmap bmp = /* there your bitmap */;
int w = bmp.getWidth();
int h = bmp.getHeight();
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int color = bmp.getPixel(x, y);
// Shift your alpha component value to the red component's.
color = (color << 24) & 0xFF000000;
bmp.setPixel(x, y, color);
}
}
If you need more effective processing, you must use (at least) getPixels method or, more preferable, native processing.
public void changeColor(Bitmap myBitmap) {
int [] allpixels = new int [myBitmap.getHeight()*myBitmap.getWidth()];
myBitmap.getPixels(allpixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
for(int i = 0; i < allpixels.length; i++)
{
if(allpixels[i] == Color.BLACK)
{
allpixels[i] = Color.RED;
}
}
myBitmap.setPixels(allpixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
}