This site requires JavaScript, please enable it in your browser!
Greenfoot back
Super_Hippo
Super_Hippo wrote ...

2014/11/13

Getting the rgb values of a transparent pixel

Super_Hippo Super_Hippo

2014/11/13

#
Hi, lately I wrote an "edge-smoothing" method. I didn't like to have such sharp color changes where you can see each pixel (e.g. after drawing a circle or a line which isn't horizontal or vertical). (This method is the main reason for saving images at the beginning and getting the java heap size error a few days ago.) Now my problem is, that if a pixel in the original picture was transparent, then this pixel will be handled as completely black (getRed(), getGreen() and getBlue() return 0).
1
image.getColorAt(x,y).getTransparency();
This never seem to return 0. Even if I create a new GreenfootImage (which is transparent by default). If it would, I could just skip all transparent pixels, so after the modification, they will still be transparent. Could it be, that the returned color from 'getColorAt' doesn't support transparency? I also tried 'getAlpha' instead of 'getTransparency'. This returns 0 for every pixel of a new transparent GreenfootImage, but somehow not for a transparent (but not empty) part of an image. (Well, but actually I have no idea about the difference between Alpha and Transparency.) Is there a way to find out the transparency of a certain pixel of an image? And if yes, is there a way to find out the rgb-values of a transparent pixel?
davmac davmac

2014/11/13

#
You seem to think that Color's "getTransparency" returns some kind of "transparency level". It doesn't. See the method's documentation. I'm pretty sure you just want to use "getAlpha".
I also tried 'getAlpha' instead of 'getTransparency'. This returns 0 for every pixel of a new transparent GreenfootImage, but somehow not for a transparent (but not empty) part of an image.
I don't understand what you mean by "transparent but not empty".
davmac davmac

2014/11/13

#
Also:
Is there a way to find out the transparency of a certain pixel of an image?
Yes, 'getAlpha' method.
And if yes, is there a way to find out the rgb-values of a transparent pixel?
getRed(), getGreen(), getBlue()? getRGB()? ... have you checked the documentation at all? :p Having said that, you might find these are unreliable for transparent pixels because the color model might be "pre-multiplied" depending on your graphics card. In that case if the alpha is 0, the red/green/blue components will also all be 0.
Super_Hippo Super_Hippo

2014/11/14

#
Oh well yes, I thought 'getTransparency' would return an int in the range 0-255 like the method with the same name in the GreenfootImage class...
I don't understand what you mean by "transparent but not empty".
I meant when I create an image, it is "empty" and when I fill it with some transparent color, it is still transparent, but not empty because there is a color. And I need to get the red/green/blue values of these colors (which is in my case either white or black). But for now, 'getAlpha' doesn't return 0 anymore if the pixel is not "empty" anymore, although it has a transparency of 0. I am not home right now, so I can't check the 'getRGB' method (which I don't really know what the 'int' which it should return tells me). I thought I could just use 'getRed' and so on. What I try is to border an image with a transparent line (which is white or black), so I can smooth the edges of the image.
Super_Hippo Super_Hippo

2014/11/14

#
Ok, 'getAlpha' seems to return the transparency of a pixel correctly. But 'getRed' (..green/blue) returns 0 if alpha is 0. So it is probably something like redvalue*alpha/255, so if alpha is 0, I can't get the value of the colors. I could add the possibility to pass one color which should be set when transparency is found, but I thought I could do it like this.
Having said that, you might find these are unreliable for transparent pixels because the color model might be "pre-multiplied" depending on your graphics card. In that case if the alpha is 0, the red/green/blue components will also all be 0.
Is there any way to still get the values? How is it depending on my graphics card? (I have two and tested both with the same results.) Would It mean that if I would upload the scenario some day, other users may see different images? Oh, and I have another question... Is it possible to make an area of an image transparent? So let's say, I have an image and in the middle should be a transparent (filled) circle. If I use 'fillOval', then it will be drawn on the color which was there before, so it stays the same color.
danpost danpost

2014/11/14

#
I have not tested it, but you could try setting each pixel using the 'setColorAt' method with an alpha value of zero and then I would believe that 'getColorAt' would return the same values as you had set (for red, green and blue).
Super_Hippo Super_Hippo

2014/11/14

#
Right now, I set the color to "255,255,255,0" (white transparent) or "0,0,0,0" (black transparent) and then I fill the whole image with this before drawing the visible rectangle (which is the image of the actor and a bit smaller than the transparent rectangle) in the middle. Do you think there could be a difference if all pixels are filled with 'setColorAt' instead? Just tested it, setting all pixels "manually" to this color doesn't let me access their rgb values either.
danpost danpost

2014/11/14

#
I must have a different graphics card. I have tested it and found that if I 'setColorAt' a pixel in an image, then using 'getColorAt().getRed", ".getGreen', and '.getBlue' on the same pixel will return the same values as I applied (as will '.getAlpha'). I used this Actor test class for testing:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import greenfoot.*;
import java.awt.Color;
 
public class TestImg extends Actor
{
    public TestImg()
    {
        GreenfootImage image = new GreenfootImage(1, 1);
        int r = Greenfoot.getRandomNumber(256);
        int g = Greenfoot.getRandomNumber(256);
        int b = Greenfoot.getRandomNumber(256);
        image.setColorAt(0, 0, new Color(r, g, b, 0));
        Color color = image.getColorAt(0, 0);
        if (color.equals(new Color(r, g, b, 0)))
            System.out.println("matched");
        else
            System.out.println("no match");
    }
}
If you create a TestImg object and cannot get "matched" to display on the terminal, then it is definitely the difference in the graphics cards. You could also try replacing line 14 with:
1
if (color.getRed() == r && color.getGreen() == g && color.getBlue() == b && color.getAlpha() == 0)
Super_Hippo Super_Hippo

2014/11/14

#
This is very interesting. I just wrote my own testing code because I saw your post before you added the code. If I set a color and just use a method to fill an area, e.g. 'fill()', then the 'alpha' value for a single pixel is returned as 255 no matter what the color was. The red/green/blue values are the realvalue*transparency/255. So if the transparency is 255, my method works as it should. But if it is 0, it only returns zeros as rgb-values. If I set every pixel manually with a color and get this color, it works as it should (it returns the rgb and alpha of the color correctly). If I use my method in between, the rgb are displayed correctly but the alpha is always 255 again for some reason. ---------------- Ooookay... I wanted to skip the transparent pixels because they should stay transparent. The problem occurred because I used the method more than once and these 'empty' spaces in the image didn't have the same values as before... I commented that part out and together with setting all transparent pixels with 'setColorAt' as you suggested, the edge smoothing works as it should now! Thank you! Does this mean to my other problem that I have to calculate every pixel in the circle and make it transparent? It would be great if it would be possible somehow to set a color when filling an area and not just drawing it above. Ok, it seems like it works now. :)
You need to login to post a reply.