I have the below image (the white bubble in the image) to draw in a canvas. When I draw the image using the code.., the image 's edge is getting black circle and rounded .. the edge's alpha is 0x00.
image.setBounds(left, top, right, bottom);
image.draw(canvas);
Expected When I draw
How could I remove the black circle??? Is the image wrong?? or Anyone know the clue, Please give me a clue.. Thanks in advance..
^^
Is your expected output taken from an image editor (Photoshop?) If so, that'll be the result of a 32-bit blend, whereas it looks like the alpha-blend on Android is being performed in 16-bits, hence the banding in the background, and halo around your image.
Presuming you're using Bitmap objects, you can check whether this is the case by calling bitmap.getConfig() to find their colour depth (from the Bitmap.Config enum).
Edit: One more thing that may be causing the halo - you say the edges of your sprite have an alpha of 0, but what about the RGB values? Make sure the ARGB is set to full-white (ARGB 0x00ffffff) rather than black (ARGB 0x00000000).
Related
I have a stack of bitmaps that I need to render one above the other. I achieve this with a relative layout and several ImageViews on top of each other which all have a Bitmap assigned to it.
This works great, but when the top layers is semi-transparent, the colours of the lower bitmap are off.
All my bitmaps use Config.ARGB_8888.
Say the top layer is red with an alpha of 50% and the bottom layer is green with an alpha of 100%.
I can either set the colour of the bitmap to red, then the alpha of the ImageView to 0.5f and it will render the green colour below fine (darker green with some red mixed in).
If I set the bitmap pixels to a 50% red like this: bmp.eraseColor(0x7Fff0000); and leave the imageView alpha on 100%, the green below will be displayed as yellow, mixing red and green, rather than overlaying it.
Unfortunately I can not use the (working) fist version because the alpha on the Bitmap above is not going to be uniform.
Is there a blend mode setting to use true colours when using semi transparent pixels in a Bitmap?
EDIT: I have also tried to set several PorterDuffXfermodes to the ImageViews but none gives the right result.
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY)); //OVERLAY//ADD//SCREEN//DARKEN//LIGHTEN
imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, paint);
Got it, needed to premultiply the alpha to get the desired result.
I am drawing some buttons on the screen. Each with a different color, but the same shape, designed in Photoshop with all sort of reflections and shines.
I want to use a single bitmap of the shape and change its color programmatically, preserving all the reflections and shadows. This is what I do right now:
Get the shape into a ARRGB_8888 bitmap (even though all colors are shades of gray)
Copy the bitmap pixels to 3 buffers: Image, Highlights, Shadows
The reference grayshade is RGB[128,128,128]
In the Highlights buffer, zero all pixels below the reference (+ threshold)
In the Shadows buffer, zero all pixels above the reference (- threshold)
From the Highlights and Shadow buffers create Highlights and Shadow Bitmaps
Draw the original grayscale image using a PorterDuffColorFilter on mode MULTIPLY
Draw on top the shadows, using the Shadows bitmap and XferMode DARKEN
Draw on top the highlights, using the Highlights bitmap and XferMode LIGHTEN
I do get a result, but I realize that the final button color is not the target color, but a darker shade of it, because the MULTIPLY mode with a reference of 128 cuts all components in half.
I tried to set the reference to a whiter shade of gray, but then the highlights get saturated.
I tried to use SRC_IN on step 7 above, and I get the target color only on areas that are neither highlights nor shadows.
See the results:
Not sure what I need to ask, but I want to get the buttons with the exact target color and its highlights and shadows. Maybe I am generating the Highlights and Shadows masks wrong, or maybe I am using the wrong blending modes. Or maybe it is something else.
I am working on a game for Android and I was wondering why whenever I draw images with transparency there seems to always be some black added to the transparent parts. This happens all over and makes some of my effects look strange.
Here is an example. The two circles are only white images with a blur but you can see when one overlaps the other it has a shadow. If I overlap two of the circles say in Inkscape I get pure white where they overlap.
I am using
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
for my blending.
Any idea why this happens and how I can avoid it?
Edit: the only thing I can think of is that the two images have the same z so maybe they are blending only with the background instead of each other?
Edit:
I changed
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
to
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_DST_ALPHA);
Here is the result I was looking for.
The only thing now is that the transparent images that I had that have a transparent black in them are ignored, which makes sense because I think the destination alpha is 1. Why would One minus source add that gray?
I figured out how to fix it.
I changed
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
to
GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);
It turns out that Android pre-multiplies the alpha of textures of PNG images when you load it (making white turn gray).
I added
vColor.r = vColor.r * vColor.a;
vColor.g = vColor.g * vColor.a;
vColor.b = vColor.b * vColor.a;
to my vertex shader to do the multiplying for my other colors.
Are you sure your content is correct? If you don't want the circles to produce any black color the color values in the image should be completely white, and the alpha channel should define the shape of the circle. Now it looks like the image has a white circle with both alpha channel and the color value fading to zero, which leads to a halo.
Are you using linear sampling? My thought could be if you have a very small image (less than say 30-40 pixels in dimension), you could be getting interpolated alpha values between the inside of the circle (alpha = 1) to the outside of the circle (alpha = 0). This would give you intermediate alpha values that result in the kind of blur effect.
Try the following code when you have the circle texture bound:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Maybe you can host the actual texture that you're using such that we can inspect it? Also please post your drawing code if this doesn't help.
You can also divide by alpha, because, the problem is, when you export your textures, Image processing software may pre-multiply your Alpha channel. I ended up with alpha division into my fragment shader. The following code is HLSL, but you can easily convert it to GLSL:
float4 main(float4 tc: TEXCOORD0): COLOR0
{
float4 ts = tex2D(Tex0,tc);
//Divide out this pre-multiplied alpha
float3 outColor = ts.rgb / ts.a;
return float4(outColor, ts.a);
}
Note that this operation is lossy, very lossy and even if it will most likely suffice in cases such as these, it's not a general solution. In your case you can totally ignore the COLOR and serve original alpha AND white in your fragment shader, e.g. return float4(1,1,1,ts.a); (convert to GLSL)
I want to create a little scratch game. The problem is, that I can't figure out how to erase pixels from an image in android (like the eraser in gimp / photoshop).
The image is an .png with alpha channel.
AIUI, drawing operations on a canvas blend a transparent pixel with the prior value of the pixel. This is by default, and you can see it by setting a canvas to black and drawing a fully transparent shape onto it, and then drawing the underlying bitmap over an image of another canvas (result: a fully black canvas), or by setting a canvas to a partially transparent color and, drawing a shape of another partially transparent color, and then drawing this over an image (result: the original image is tinted by the first color, outside the shape; within the shape, it's tinted by both transparent colors). I don't know the blending method used by default, and looking through the docs just makes me wish I knew what book to buy so I can understand how to use what's available.
So I would set pixels to transparent by setting them 'directly', with Bitmap methods, rather than with canvas operations. Although if you need to punch a transparent shape into an overlay, you can draw the shape with a solid non-transparent color, and then manipulate the bitmap directly, mapping this color to the transparent color.
Bitmap docs. Prefer getPixels() and setPixels() to a method-call per pixel.
EDIT: ...er, did I misunderstand? You want to 'erase' pixels as in a paint program? Then just draw whatever the background color is. There's no erasure involved.
I am trying to subclass ImageView and draw something on Bitmap. However I cannot find a way to get the Rect in which Bitmap is drawn. I can only get the Rect in which ImageView is drawn by getDrawingRect(Rect) method of ImageView. Below is an illustration of what I want to get:
The Rect I want is the blue one. Thanks in advance.
The given image will be drawn in the ImageView based on the attributes given e.g., height, width, scaling factors, etc.
So that the getDrawingRect() method giving the entire area of ImageView. If you change the drawable inside ImageView the blue colored area may change based on the image properties and imageview properties. But the yellow colored area won't change because it is fixed and based on the ImageView only, its independent of image displayed.
I think no chance to get the Rect of bitmap drawn. Don't think my answer is 100% correct, it is just a suggestion only.
You may get information about blue colored area from Drawing Cache. Try it once.
I hope it may help you.