I have a picture (http://imgur.com/lIfzpWB.png) which I opening via Bitmap.decodeFile(path);.
But what I can do with my bitmap to get this picture (http://imgur.com/GHltevM.png) as result?
I think I need to apply some kind of color mask on the Bitmap. How I can do that?
UPD I used following code to achieve my result:
image.setImageDrawable(convert(original, 0x7F00FF00));
public BitmapDrawable convert(Bitmap src, int color) {
BitmapDrawable temp = new BitmapDrawable(src);
temp.setColorFilter(new LightingColorFilter(0, color));
return temp;
}
UPD I did my code work! I've just replaced new LightingColorFilter(0, color) with new LightingColorFilter(color, 0). Thank you guys for all your help!
try something like this.
Bitmap bitmap = Bitmap.decodeFile(path);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColorFilter(new LightingColorFilter(0, 0x005500));
canvas.drawPaint(paint);
This should do what you want (I haven't tried it), although the value for the lightingColorFilter will probably have to be tweaked for the effect you are trying to achieve.
you need to remove the green color channel.
you can open the file as buffered image as the variable named `imagè and then use the following code:
for(int i=0;i<image.getWidth();i++)
for(int j=0;j<image.getHeight();j++){
Color c=new Color(image.getRGB(i,j));
int pixel=c.getRed()<<16|c.getBlue();
image.setRGB(pixel);
}
the resultant `imagè will be your image with no green channel.
Related
I am developing a project on image processing where I have to fill the digitized images of cracked paintings. I have to convert a color image to grayscale, performing some calculations on the 2D Array of the gray image and writing it back as gray image. The code for this is:
BufferedImage colorImage=ImageIO.read(new File(strImagePath));
BufferedImage image = new BufferedImage(colorImage.getWidth(),colorImage.getHeight(),BufferedImage.TYPE_BYTE_GRAY);
Graphics g = image.getGraphics();
g.drawImage(colorImage, 0, 0, null);
g.dispose();
ImageIO.write(image,"PNG",new File("Image.PNG"));
BufferedImage imgOriginal=ImageIO.read(new File("Image.PNG"));
int width=image.getWidth();
int height=image.getHeight();
BufferedImage im=new BufferedImage(width,height,BufferedImage.TYPE_BYTE_GRAY);
int arrOriginal[][]=new int[height][width];
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
arrOriginal[i][j]=imgOriginal.getRGB(j,i)& 0xFF;
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
im.setRGB(j,i,arrOriginal[i][j]);
ImageIO.write(im,"PNG",new File("Image1.PNG"));
But the output image is very much darker, I am not getting the original image back (I have not done any changes yet).
I think there should be some changes in setRGB() statement but I don't know what.
To write image back, I have also tried:
`
BufferedImage im = new BufferedImage(width,height,BufferedImage.TYPE_BYTE_GRAY);
WritableRaster raster = im.getRaster();
for(int i=0;i<height;i++)
for(int j=0;j<width;j++)
raster.setSample(j,i,0,arrOriginal[i][j]);
`
But it also don't give me original image back.
Can anyone provide me the solution of this problem?
Thanks in advance.
I don't know anything about Java-based image processing, but I do know quite a lot about image processing in general, so I will see if I can give you any ideas. Please don't shoot me if I am wrong - I am just suggesting an idea.
In a greyscale image, the red, green and blue values are all the same, i.e. Red=Green=Blue. So, when you call getRGB and do the AND with 0xff, you are probably getting the blue component only, but that is ok as the red and green are the same - because it's greyscale.
I suspect the problem is that when you write it back to create your new output image, you are only setting the blue component and not the red and green - which should still be the same. Try writing back
original pixel + (original pixel << 8 ) + (original pixel <<16)
so that you set not only the Blue, but also the Red and Green components.
I am trying to draw a transparent circle on a Bitmap in android. I have three primary variables:
mask = Bitmap.createBitmap(this.getWidth(),this.getHeight(), Bitmap.Config.ARGB_8888);
Canvas can = new Canvas(mask);
Paint clear = new Paint();
If I do the following, I get my expected results:
clear.setColor(Color.TRANSPARENT);
can.drawRect(new Rect(0,0,this.getWidth(),this.getHeight()),clear);
However, if I draw something else on the canvas first, then try to clear it out with transparency, the old data remains. For example:
clear.setColor(Color.argb(255,255,0,0));
can.drawRect(new Rect(0,0,this.getWidth(),this.getHeight()),clear);
clear.setColor(Color.TRANSPARENT);
can.drawRect(new Rect(0,0,this.getWidth(),this.getHeight()),clear);
I only see a giant red square. The bottom two lines are supposed to "erase" the filled red to make it transparent again. Ultimately the mask is drawn on another canvas like this:
#Override
public void onDraw(Canvas c)
{
c.drawBitmap(mask,0,0,null);
super.onDraw(c);
}
As it turns out it does have to do with the Paint object and setting the Xfermode...
mask = Bitmap.createBitmap(this.getWidth(),this.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas can = new Canvas(mask);
Paint clear = new Paint();
clear.setColor(Color.argb(255,255,0,0));
can.drawRect(new Rect(0,0,this.getWidth(),this.getHeight()),clear);
PorterDuffXfermode xfer = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
clear.setXfermode(xfer);
clear.setColor(Color.TRANSPARENT);
can.drawCircle(this.getWidth()/2, this.getHeight()/2, this.getHeight()/2, clear);
I have the following code which I got from a youtube tutorial for drawing canvas:
(https://www.youtube.com/watch?v=6NBt36fO0iw):
#Override
protected void onDraw(Canvas canvasporch) {
canvasporch.drawColor(Color.BLACK);
for (int i = temps.size() - 1; i >= 0; i--){
temps.get(i).onDraw(canvasporch);
for (Sprite sprite : sprites){
sprite.onDraw(canvasporch);
This works just fine. The only problem is instead of having the color Black as background, I want to display an image from my drawable folder as the background for my sprites. I've tried using drawBitmap() but I cannot seem to make it work. Thanks.
1) Create a member variable to store the Bitmap:
Bitmap spriteBackground;
2) In onCreate() (or some other initialization function) load the bitmap from the drawable:
spriteBackground = BitmapFactory.decodeResource(getResources(), R.drawable.sprite_background);
3) Draw the bitmap using drawBitmap() inside onDraw():
canvasporch.drawBitmap(spriteBackground, 0, 0, null);
If you want to scale the bitmap to cover the canvas then either scale it at load time using createScaledBitmap (uses more memory) or apply a matrix transform to the canvas (possibly slower).
Another way is to pass the canvas bounds to drawBitmap(), like this:
canvasporch.drawBitmap(spriteBackground, null, canvasporch.getClipBounds(), null);
I have a canvas and a simple bitmap for background image, fills the whole screen. I created a rect painted black and set it's alpha to 250 in order to make a "dark" effect on the background image. My aim to make a simple circle object that reveals the place it's hovering above. I tried thinking in many ways how to excecute it and failed.
I think the best way is to create a simple circle that manages to decrease the darkness alpha on the position it hovers above, but I have no idea how to do it.
The relevant part of my code:
private ColorFilter filter = new LightingColorFilter(Color.BLACK, 1);
private Paint darkPaint = new Paint(Color.BLACK), paint = new Paint(), paint2 = new Paint();//The style of the text and dark.
public DarkRoomView(Context context) {
super(context);
myChild = this;
darkPaint.setColorFilter(filter);
darkPaint.setAlpha(250);
paint2.setAlpha(10);
paint.setAlpha(50);
}
private void loadGFX() {//Loads all of this view GFX file.
backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.darkroomscreen);
lightImage = BitmapFactory.decodeResource(getResources(), R.drawable.light);
}
private void drawGFX(Canvas canvas) {
canvas.drawBitmap(backgroundImage, 0, 0, paint2);//The backgeound image.
canvas.drawRect(0, 0, WIDTH, HEIGHT, darkPaint);//The darkness.
canvas.drawBitmap(lightImage, 50, 50, paint);//A spotlight.
}
Any ideas how I should get it done?
Thanks!
For the spotlight, you could draw a circle of the original image over the darkness. You'd simply need to find the correct rectangle of the original image (based on where your finger is), and then draw a circle of that particular rectangle over the darkness. Trying to look "through" the darkness won't really get you anywhere; you need to place something over it.
By the time you draw the "spotlight", you've already darkened the image with the rectangle. It would be difficult to recover information lost during that draw.
A more flexible approach would be to draw a dark rectangle with a spotlight in a separate image (that is, compose the "darkness" and spotlight alpha and color mask image first), and then draw that mask image on top of the background as a separate step. This would also let you easily do things like e.g. give the spotlight fuzzy borders.
** Important update, see below! **
I am creating a program that changes the pixels of a BufferedImage to a certain color when that pixel fulfills a set of conditions in Java. However, when I write the image to disk, the pixels that should be colored are instead black.
First I define the color, using RGB codes:
Color purple = new Color(82, 0, 99);
int PURPLE = purple.getRGB();
Then I read the image I want to alter from a File into a BufferedImage called "blank":
BufferedImage blank = ImageIO.read(new File("some path"));
Now, loop through the pixels, and when a pixel at location (x, y) matches a criteria, change its color to purple:
blank.setRGB(x, y, PURPLE);
Now, write "blank" to the disk.
File output = new File("some other path");
ImageIO.write(blankIn, "png", output); // try-catch blocks intentionally left out
The resulting file should be "blank" with some purple pixels, but the pixels in question are instead black. I know for a fact that the issue is with setRGB and NOT any import or export functions, because "blank" itself is a color image, and gets written to file as such. I read around and saw a lot of posts recommending that I use Graphics2D and to avoid setRGB, but with no discussion of pixel-by-pixel color changing.
I also tried direct bit manipulation, like this:
blank.setRGB(x, y, ((82 << 16) + (0 << 8) + 99));
I'm probably doing that wrong, but if I put it in correctly it wouldn't matter, because the pixels are getting set to transparent when I do this (regardless of what the numbers say, which is very strange, to say the least).
** When I try this:
blank.setRGB(x, y, Color.RED.getRGB());
My output file is grayscale, so that means setRGB is, in fact, modifying my picture in grayscale. I think this is actually a rather simple issue, but the solution eludes me.
Based on the insights in https://stackoverflow.com/a/21981173 that you found yourself ... (a few minutes after posting the question) ... it seems that it should be sufficient to simply convert the image into ARGB directly after it was loaded:
public static BufferedImage convertToARGB(BufferedImage image)
{
BufferedImage newImage = new BufferedImage(
image.getWidth(), image.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return newImage;
}
The original image that was imported into Java was actually grayscale, so when Java read it into the BufferedImage, it simply imported it as a grayscale BufferedImage. By adding a very small but imperceptible colored dot in the corner of my image, I was able to get Java to output a correctly colored image.
Unfortunately, this is only a half solution, because I do not know how to fix this programmatically.
SOLUTION:
Convert the BufferedImage from grayscale to ARGB with this snippet:
BufferedImage blank2 = blank;
// Create temporary copy of blank
blank = new BufferedImage(blank.getWidth(), blank.getHeight(), BufferedImage.TYPE_INT_ARGB);
// Recreate blank as an ARGB BufferedImage
ColorConvertOp convert = new ColorConvertOp(null);
// Now create a ColorConvertOp object
convert.filter(blank2, blank);
// Convert blank2 to the blank color scheme and hold it in blank
You want to add this right after blank = ImageIO.read(new File("some path")).