How can I set the alpha of a bitmap pre-setHasAlpha? - android

I have a Bitmap and I need to set some of its pixels to transparent. Although I'm creating the Bitmap with Config.ARGB_8888, when I call Bitmap.hasAlpha() on it, it returns false. I can't use Bitmap.setHasAlpha() because that was only added in API level 12 whereas my minimum supported API needs to be 9. How can I do this?

Here you go:
Paint paint = new Paint();
paint.setAlpha(100);
canvas.drawBitmap(bitmap, src, dst, paint);
How to change a bitmap's opacity?
Edit:
//Create an array of pixels of the bitmap using Bitmap getPixels function
//Traverse through the pixels array and if that pixel matches your condition to change it to transparent
// Change the color of that pixel to transparent using Color.Transparent
//Finally set them back using Bitmap setPixels function
Example code:
import android.graphics.Color;
int[] pixels = new int[myBitmap.getHeight()*myBitmap.getWidth()];
myBitmap.getPixels(pixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
//traverse through pixel array and if condition is met
pixels[i] = Color.TRANSPARENT;
myBitmap.setPixels(pixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
how to change the color of certain pixels in bitmap android

// Convert red to transparent in a bitmap
public static Bitmap makeAlpha(Bitmap bit) {
int width = bit.getWidth();
int height = bit.getHeight();
Bitmap myBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
int [] allpixels = new int [ myBitmap.getHeight()*myBitmap.getWidth()];
bit.getPixels(allpixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(),myBitmap.getHeight());
myBitmap.setPixels(allpixels, 0, width, 0, 0, width, height);
return myBitmap;
}
The above code is equivalent to setHasAlpha. Give it a Bitmap, and it will return a Bitmap where HasAlpha is true, and will therefore be able to have transparency. This works in API level 8. I have not tested it in anything lower.

Related

Change the color balance of a Drawable

It is possible to change the color balance of a Drawable ?
For example, I would like to convert
to =>
I try this but it change all the colors of my Drawable to one unique color :
Drawable drawable; // my drawable
float r = Color.red(110) / 255f;
float g = Color.green(150) / 255f;
float b = Color.blue(200) / 255f;
ColorMatrix cm = new ColorMatrix(new float[] {
// Change red channel
r, 0, 0, 0, 0,
// Change green channel
0, g, 0, 0, 0,
// Change blue channel
0, 0, b, 0, 0,
// Keep alpha channel
0, 0, 0, 1, 0,
});
ColorMatrixColorFilter cf = new ColorMatrixColorFilter(cm);
drawable.setColorFilter(cf);
I specify I don't want to split my src image into 2 or more layers and colorify one of them.
You can apply a tint with the desired color to your image using mutate().setColorFilter(), and set the Drawable with the new color into your ImageView:
ImageView imgImagen = (ImageView)findViewById(R.id.myImageView);
Drawable myImage = getResources().getDrawable( R.drawable.boy );
//Using red color.
myImage.mutate().setColorFilter(0xffff0000, PorterDuff.Mode.MULTIPLY);
imgImagen.setImageDrawable(myImage);
For example using this ImageView,
<ImageView
android:id="#+id/myImageView"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="#drawable/boy"
android:contentDescription="" />
you will have this image as result:
You can use too the color defined in your example:
myImage.mutate().setColorFilter(Color.argb(255, 110, 150, 200), PorterDuff.Mode.MULTIPLY);
I can see that your character have eyes and some attribute which need to be safe during color change, so we need more control on that resource therefore we will convert it to bitmap:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.brown_man);
Your bitmap might be not mutable so in order to make it mutable:
Bitmap myBitmap = bitmap.copy(Bitmap.Config.RGB_565, true);
Then we have to getPixels() And re setPixels() with specified color:
int[] pixels = new int[myBitmap.getHeight() * myBitmap.getWidth()];
myBitmap.getPixels(pixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
for (int i = 0; i < pixels.length; i++) {
if (pixels[i] == color /*Color to change int value*/)
pixels[i] = newColor /*The new color you want to change*/;
}
myBitmap.setPixels(pixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
Thus, you can use this bitmap as you wish.
Some things to take considering:
Your resource character must have a height resolution color to make it easy to specify and change.

How to merge 2 bitmap with config ALPHA_8 in android?

If I load a bitmap with ALPHA_8 it will create an bitmap with the a greyscale and transparancy. This is exactly what I want.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test_bitmap, options);
I want to merge two bitmaps. To do so I create a canvas with ALPHA_8 and draw the same bitmap on the canvas.
But the result is different. It will keep the alpha, but everything what was grey will be black. So I see only the contours and no greyscale.
resultBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ALPHA_8);
resultCanvas = new Canvas(resultBitmap);
resultCanvas.drawBitmap(bitmap, 0, 0, null);
I found 2 workarounds.
A) Use ARGB_8888 instead of ALPHA_8, but this will result in a far larger image.
resultBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
B) Use a color matrix to convert the image to alpha channel, but this will result in the grey to be semi transparant, instead of a grey scale.
float[] matrix = new float[] {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
-1f, 0, 0, 1f, 0};
Paint grayToAlpha = new Paint();
grayToAlpha.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(matrix)));
resultCanvas.drawBitmap(bitmap, 0, 0, grayToAlpha);
Both workarounds are not perfect. So my question is:
Is there a way to get the same result with the canvas as with the bitmap?
Or
Is there a better way of merging two bitmaps with ALPHA_8 together?

Efficient Bitmap masking with black and white alpha mask in Android

I wanted to mask a Bitmap with a black and white alpha mask. My mask image is black and white, the BLACK area means TRANSPARENT and WHITE area means OPAQUE.
What I need is:
When I use this mask image to mask any other image, the area of resultant image should TRANSPARENT if the corresponding area of mask image is BLACK. Otherwise the area of resultant image should be OPAQUE.
I have attached the sample images. Please help me with this guys.
Sample Image:
Sample Image for Masking
What I have tried so far:
The following methods work fine. But they are very slow. I needed some solution that is efficient in terrms of speed and memory than these methods.
First Method:
int width = rgbDrawable.getWidth();
int height = rgbDrawable.getHeight();
if (width != alphaDrawable.getWidth() || height != alphaDrawable.getHeight()) {
throw new IllegalStateException("image size mismatch!");
}
Bitmap destBitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
int[] pixels = new int[width];
int[] alpha = new int[width];
for (int y = 0; y < height; y++)
{
rgbDrawable.getPixels(pixels, 0, width, 0, y, width, 1);
alphaDrawable.getPixels(alpha, 0, width, 0, y, width, 1);
for (int x = 0; x < width; x++)
{
// Replace the alpha channel with the r value from the bitmap.
pixels[x] = (pixels[x] & 0x00FFFFFF) | ((alpha[x] << 8) & 0xFF000000);
}
destBitmap.setPixels(pixels, 0, width, 0, y, width, 1);
}
alphaDrawable.recycle();
rgbDrawable.recycle();
return destBitmap;
Second Method
float[] nlf = new float[] {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 0, 0, 0, 0};
ColorMatrix sRedToAlphaMatrix = new ColorMatrix(nlf);
ColorMatrixColorFilter sRedToAlphaFilter = new ColorMatrixColorFilter(sRedToAlphaMatrix);
// Load RGB data
Bitmap rgb = rgbDrawable;
// Prepare result Bitmap
Bitmap target = Bitmap.createBitmap(rgb.getWidth(), rgb.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(target);
c.setDensity(Bitmap.DENSITY_NONE);
// Draw RGB data on our result bitmap
c.drawBitmap(rgb, 0, 0, null);
// At this point, we don't need rgb data any more: discard!
rgb.recycle();
rgb = null;
// Load Alpha data
Bitmap alpha = alphaDrawable;
// Draw alpha data on our result bitmap
final Paint grayToAlpha = new Paint();
grayToAlpha.setColorFilter(sRedToAlphaFilter);
grayToAlpha.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
c.drawBitmap(alpha, 0, 0, grayToAlpha);
// Don't need alpha data any more: discard!
alpha.recycle();
alpha = null;
return target;

ColorMatrixColorFilter does not affect alpha values less than 255

I have a method that take a Bitmap and a color, and converts all the pixels on the Bitmap to that color, while keeping the original's alpha values. In addition, the method is written so that as the color passed in gets darker, the Bitmap is made more transparent rather than darker. If the color passed in is completely black, then the Bitmap should be made entirely transparent instead of black.
public static Bitmap colorImage(Bitmap img, int red, int green, int blue) {
int max = blue;
if (red >= green && red >= blue)
max = red;
else if (green >= red && green >= blue)
max = green;
double scale = 255.0 / max;
red = (int)(scale * red);
green = (int)(scale * green);
blue = (int)(scale * blue);
Bitmap resultBitmap = img.copy(Bitmap.Config.ARGB_8888, true);
float[] colorTransform = {
0, 0, 0, 0, red,
0, 0, 0, 0, green,
0, 0, 0, 0, blue,
0, 0, 0, (float) (1f / scale), 0};
ColorMatrix colorMatrix = new ColorMatrix(colorTransform);
ColorMatrixColorFilter colorFilter = new ColorMatrixColorFilter(colorMatrix);
Paint paint = new Paint();
paint.setColorFilter(colorFilter);
Canvas canvas = new Canvas(resultBitmap);
canvas.drawBitmap(resultBitmap, 0, 0, paint);
return resultBitmap;
}
There is an issue with making the Bitmap transparent.
If I set the color matrix so that it is as follows,
float[] colorTransform = {
0, 0, 0, 0, red,
0, 0, 0, 0, green,
0, 0, 0, 0, blue,
0, 0, 0, 0, 0};
the entire Bitmap should be made completely transparent. However, this only works correctly if the original Bitmap has no transparency at all. If the Bitmap has only alpha values of 255 for all of its pixels, then the result is completely transparent. However, if the Bitmap has any pixel with an alpha value of less than 255, the final image will not be transparent, but will have the same alpha values as the original.
Can anybody tell why?
Thanks in advance.
Bitmaps by default have black backgrounds. Setting the Bitmap's background to transparent resolves the issue.
This can be done by adding resultBitmap.eraseColor(Color.argb(0, 0, 0, 0)); after resultBitmap is declared, changing canvas.drawBitmap(resultBitmap, 0, 0, paint); to canvas.drawBitmap(img, 0, 0, paint);.

how to change the color of certain pixels in bitmap android

i've a bitmap that i want to change certain pixels. i've got the data from the bitmap into an array, but how would i set a pixels colour in that array?
thanks
int[] pixels = new int[myBitmap.getHeight()*myBitmap.getWidth()];
myBitmap.getPixels(pixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
for(int i =0; i<500;i++){
//Log.e(TAG, "pixel"+i +pixels[i]);
To set the colors of the pixels in your pixels array, get values from the static methods of Android's Color class and assign them into your array. When you're done, use setPixels to copy the pixels back to the bitmap.
For example, to turn the first five rows of the bitmap blue:
import android.graphics.Color;
int[] pixels = new int[myBitmap.getHeight()*myBitmap.getWidth()];
myBitmap.getPixels(pixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
for (int i=0; i<myBitmap.getWidth()*5; i++)
pixels[i] = Color.BLUE;
myBitmap.setPixels(pixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
You can also set a pixel's color in a Bitmap object one at a time without having to set up a pixel buffer with the setPixel() method:
myBitmap.setPixel(x, y, Color.rgb(45, 127, 0));

Categories

Resources