I am working with bitmap images whose transparent parts are colored in magenta (in some languages it is possible to set a color as transparent). I try to transparent pixels which are in magenta in the original bitmap image.
I load the bitmap from SD-card:
Bitmap bitmap = BitmapFactory.decodeFile(myImagePath);
copy it to another bitmap to make it mutable:
Bitmap bitmap2 = bitmap.copy(Bitmap.Config.ARGB_8888,true);
Then scan it pixel by pixel to find pixels in magenta and try to change their transparency.
for(int x=0;x<bitmap2.getWidth();x++){
for(int y=0;y<bitmap2.getHeight();y++){
if(bitmap2.getPixel(x, y)==Color.rgb(0xff, 0x00, 0xff))
{
int alpha = 0x00;
bitmap2.setPixel(x, y , Color.argb(alpha,0xff,0xff,0xff)); // changing the transparency of pixel(x,y)
}
}
}
But those pixels which I expect to become transparent are converted to black. By changing the alpha, I found that the final color varies from the mentioned color in argb() (without mentioning the alpha) to black. For instance, Color.argb(0xff,0xff,0xff,0xff) gets white, Color.argb(0x80,0xff,0xff,0xff) gets gray and Color.argb(0x00,0xff,0xff,0xff) gets black.
I don't undrestand what's wrong.
Could it be possible that there is no alpha channel and I should first set/define it? if yes, how?
EDIT1:
According to the comment of Der Gol...lum I have modified my code:
Paint mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
mPaint.setAntiAlias(true);
Bitmap bitmap = BitmapFactory.decodeFile(myBackImagePath).copy(Bitmap.Config.ARGB_8888 , true);
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(bitmap, 0, 0, mPaint);
if(bitmap.getPixel(0, 0)==Color.rgb(0xff, 0x00, 0xff))
{
for(int x=0;x<bitmap.getWidth();x++){
for(int y=0;y<bitmap.getHeight();y++){
if(bitmap.getPixel(x, y)==Color.rgb(0xff, 0x00, 0xff))
{
bitmap.setPixel(x, y,Color.TRANSPARENT);
}
}
}
But the result is more or less the same. Using different PorterDuffModes causes either transparency of the entire bitmap or make the targeted pixels black:
Would anybody have any idea?
I could finally find the problem.
My png images had no alpha channel or maybe their alpha channel were not activated.
what I did to solve this problem is to add:
bitmap.setHasAlpha(true);
and it works how I expected.
Related
I have the following image:
Now I’d like to filter this image to different colors at runtime. E.g. I want to be able to generate a green version of it, where the lower part is of a darker green, and the top-left part is lighter green.
How can I do this? Is this even possible?
I have tried filtering the bitmap like as follows:
private static Bitmap applyColorFilter(Bitmap source, int color) {
Bitmap empty = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight());
Canvas c = new Canvas(empty);
Paint p = new Paint();
PorterDuffColorFilter pdcf = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
p.setColorFilter(pcdf);
c.drawBitmap(empty, 0, 0, p);
source.recycle();
return empty;
}
I have tried all of PorterDuff.Modes, but none of them really works. Sometimes (e.g. SRC_IN) I see the circle totally filled with the new color, without any shading. In other cases I see a square.
I have thought about generating a source image with no color itself, and to render its shading with an alpha channel. However, I’m not sure that would work. I want the resulting image to be fully opaque (apart from the outer shadow you can see above).
I have found a solution using ColorMatrixColorFilter.
// Take values from the destination color
int destA = (color >> 24);
int destR = (color >> 16) & 0xff;
int destG = (color >> 8) & 0xff;
int destB = color & 0xff;
// Give the same weight to source R,G,B, thus grasping the intensity
// -> the shading overlay
float mean = 0.33f;
ColorMatrixColorFilter cm = new ColorMatrixColorFilter(
new float[]{
mean,mean,mean,0,destR,
mean,mean,mean,0,destG,
mean,mean,mean,0,destB,
0,0,0,1,destA }
);
Paint p = new Paint();
p.setColorFilter(cm);
...
Inevitably, this slightly changes (brightens) the destination color, so I’ll wait some days for a better solution. For my input image, I have better results by lowering the mean value to approx. 0.2.
The same result could probably be obtained with a LightningColorFilter.
I want to set home wallpaper with white bitmap:
Bitmap bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(0xfff);
WallpaperManager wall = WallpaperManager.getInstance(this);
try {
wall.setBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
And the wallpaper becomes black. What's wrong is here?
Just add bitmap.eraseColor(Color.WHITE);
as second line
My first guess would be your color choice, assuming this is the value in your actual code and not edited.
Color ints in java take the form ARGB, so Color.WHITE is 0xFFFFFFFF, Color.BLUE is 0xFF0000FF, etc.
The color in your code (0xFFF) would expand to 0x00000FFF which is Blue with a little green mixed in, but the alpha channel is zero, so the Canvas is basically written with a transparent color.
If you are using standard colors, I would stick to the constants in the Color class as parameters here, but if you want to define the color yourself, remember to place the full color or use Canvas.drawRGB() instead.
I get my bitmap, use it as a shader tile mode.
The PNG is mostly alpha except for the shape outline to draw.
Except it draws the outline, but is surrounded by black, not seethrough (alpha).
pnt.reset();
if(backgroundColor == 1)
{
pnt.setColor(myColor);
pnt.setStyle(Paint.Style.FILL);
}
m_canvas.drawPath(path, pnt);
//fillBMP = getBitmapFromAsset(m_context, "brush.png");
fillBMP = BitmapFactory.decodeFile(mySDPath + "brush.png");
fillBMPshader = new BitmapShader(fillBMP, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
pnt.setShader(fillBMPshader);
m_canvas.drawPath(path, pnt);
Example below of the brush on left. But result it draws on right.
You should set XferMode on your Paint object. More specifically you got to use PorterDuffXferMode MULTIPLY.
Here is a similar question : Android color overlay - PorterDuff modes
I'm having trouble setting an alpha value of a region path drawn on a bitmap, using SurfaceView.
I'm creating my bitmap and erase with a black color (and 255 as alpha)
bitmap = Bitmap.createBitmap(480, 724, Bitmap.Config.ARGB_8888);
bitmap.eraseColor(0xFF000000);
Canvas canvas = new Canvas(bitmap);
Next, in my onDraw method I draw a path on the bitmap with his own alpha, white color as stroke, black as fill color and 1 as alpha value :
Paint border = new Paint();
border.setStyle(Paint.Style.STROKE);
border.setStrokeWidth(1);
border.setStrokeCap(Paint.Cap.BUTT);
border.setStrokeJoin(Paint.Join.MITER);
border.setColor(Color.WHITE);
Paint inside = new Paint();
inside.setAntiAlias(false);
inside.setStyle(Paint.Style.FILL);
int alpha = 1<<24;
inside.setColor(alpha);
canvas.drawBitmap(bitmap,0,0, null);
canvas.drawPath(path, border);
canvas.drawPath(path, inside);
Finally, in my onTouchEvent method, i'm doing this :
int index = bitmap.getPixel((int)event.getX(), (int)event.getY());
int alpha = index >>> 24;
Log.v("TAG", " Region path alpha :"+ String.valueOf(alpha));
So, when I click inside the path region, I'm expecting to have 1 (0x01) as alpha value,
but instead I'm still have 255 (0xFF). What's wrong with that ? Thanks in advance.
I am trying this in usual Java, and getting no errors ! probably you should try debugging the value of index. Output the value of index and check, or just try
Color.alpha(index)
http://developer.android.com/reference/android/graphics/Color.html#alpha(int)
I have a white background image, it is not fit for my app's black background.
I want to make it have black background, or reverse all the colors in the bitmap image.
How can I do that?
Get the width and the height of the bitmap. Store the pixels in array, then iterate each pixel, test for white color (hex value) if it is true than swap it with value for black. This is not the best solution. Why dont you just load black bitmap?
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.r); //example,
int[] pixels = new int[bm.getWidth()*bm.getHeight()];
bm.getPixels(pixels, 0, bm.getWidth(),0, 0, bm.getWidth(), bm.getHeight()); //filling the array, this might throw some outofboundaryindex exception for the array, check again.
int i = 0;
while(i!=bm.getWidth()*bm.getHeight())
{
if(pixels[i]==hexforblack)
{
swap it with hex of white
}
i++;
}
Here you can find hex values of the colors
http://www.w3schools.com/html/html_colors.asp