Jump to content
  • Advertisement
Sign in to follow this  
Addictman

[java] Pixel-modifying images?

This topic is 5083 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. i am just wondering if there is a defacto standard for modifying the colorvalues of clusters and/or individual pixels of an image? Right now, I just use BufferedImage's setRGB method. When I reach about 5000 modifications (individual pixels) pr. loop-run, things tend to get choppy at intervals. I also looked at writableraster's. Anyone got any bright ideas and solutions for me, how I can safely modify huge amounts of pixels quickly? I'll stress that I'm looking for performance here, not necessarely clean and readable code, so anything that's fast goes. Thanks.

Share this post


Link to post
Share on other sites
Advertisement
It's for some effects that look really nice ;) I guess it doesnt really matter exactly what the specifics of my needs are. So, any tips?

Share this post


Link to post
Share on other sites
Don't use setRGB. Instead, you can get access to the image's pixels directly:

// create image (make sure the format you set matches the type of pixel data you want)
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

// get data array
DataBufferInt db = (DataBufferInt) img.getRaster().getDataBuffer();
int[] pixels = db.getData();

// set pixel at x, y to color c (which should be a RGB value)
pixels[y*width + x] = c;


I'm not sure I have the exact method calls written there, but it should be close.

To draw the image, you don't need to do anything extra; just use drawImage.

Also, if you also want alpha in your image, use BufferedImage.TYPE_INT_ARGB.

Share this post


Link to post
Share on other sites
Modifying the raster is what I do for those intensive operations. It is a HUGE speed-up over getting and setting pixels with the BufferedImage methods. When I started doing that, my graphics operations got about eight times faster with no further optimization.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Could you post your resulting code to share your experience?
Or could you, TheBluMage post your eight times faster raster code?

Share this post


Link to post
Share on other sites
Man, I wish I had those kinds of options in J2ME :( With MIDP 2.0 you can at least extract a data array from an Image, and create an Image from a data array, but the created version is a *new, immutable* one, which implies it has to copy your array and then GC the old thing, and... ugh. You'd think they'd give you *better* low-level access when working with a more resource-constrained system yeah? :s

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Could you post your resulting code to share your experience?
Or could you, TheBluMage post your eight times faster raster code?

Sure. It's a method designed to skew a BufferedImage inward at the top and store the resulting image in another (or the same) BufferedImage. I didn't have the old method with the get and set pixel methods, but I reconstructed it as well as I could.

Using Get and Set Pixel methods:

public static void skewInTop(BufferedImage image, BufferedImage dest, float topSkinny) {

int width = image.getWidth();
float lineIncrem = (1F - topSkinny) / image.getHeight();
int pixIncrem;
int middle = width >> 1;
int curFromOffset;
int curToOffset;
int halfShouldBe;
int middleDivHalf;
int middleModHalf;
int height = image.getHeight();

for(int i = 0; i != height; ++i) {

halfShouldBe = (int) (topSkinny * middle);
topSkinny += lineIncrem;

middleDivHalf = middle / halfShouldBe;
middleModHalf = middle % halfShouldBe;

for(curFromOffset = 0, curToOffset = 0, pixIncrem = 0; ; ++curToOffset) {

curFromOffset += middleDivHalf;
pixIncrem += middleModHalf;

if(pixIncrem > halfShouldBe) {

++curFromOffset;
pixIncrem -= halfShouldBe;

}

if(!(curFromOffset < middle)) break;
dest.setRGB(middle - curToOffset, i, image.getRGB(middle - curFromOffset, i));
dest.setRGB(middle + curToOffset, i, image.getRGB(middle + curFromOffset, i));

}

}

}




Using Raster (assumes 32-bit integer sized pixels):

public static void skewInTop(BufferedImage image, BufferedImage dest, float topSkinny) {

int[] destRaster = ((DataBufferInt) dest.getRaster().getDataBuffer()).getData();
int[] raster = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
int width = image.getWidth();
float lineIncrem = (1F - topSkinny) / image.getHeight();
int pixIncrem;
int middle = width >> 1;
int curFromOffset;
int curToOffset;
int halfShouldBe;
int value;
int middleDivHalf;
int middleModHalf;

for(int i = 0; i != raster.length; i += width) {

halfShouldBe = (int) (topSkinny * middle);
topSkinny += lineIncrem;

middleDivHalf = middle / halfShouldBe;
middleModHalf = middle % halfShouldBe;

for(curFromOffset = 0, curToOffset = 0, pixIncrem = 0; curToOffset != halfShouldBe; ++curToOffset) {

curFromOffset += middleDivHalf;
pixIncrem += middleModHalf;

if(pixIncrem > halfShouldBe) {

++curFromOffset;
pixIncrem -= halfShouldBe;

}

value = i + middle;
destRaster[value - curToOffset] = raster[value - curFromOffset];
destRaster[value + curToOffset] = raster[value + curFromOffset];

}

}

}




EDIT: Note that since I deleted the old slower method, I optimized the new one more, so now the raster one is well over eight times faster than the other I reconstructed, despite the fact that these speed optimizations were applied to it as well.

[Edited by - TheBluMage on August 19, 2004 2:45:44 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!