I was wondering if someonecould explain the theory of having your own pallette for yourr images? How does it work? How do you create a pallette and how do you use it on your images? Basically right now I have png files that I draw through darwImage(). I would like to use a custom pallette to do effects but dso not know where to start.
Palette based effects aren’t done much anymore. They are really only useful if you are running on a palette-based display (256 colours or less).
If you want to experiment use BufferedImages with an INDEXed pixel format.
In a bitmap image you have the color info per pixel, in the case of RGBA images you have 4 bytes to store the color of each pixel.
In the indexed images (GIF, PNG) there is a palette of colors, and the info per pixel is the index for the color to be displayed. The info in each pixel depends on the number of colors in the palette, with 8 bits, 256 colors can be indexed (0…255)
Example 1: 3 color image 200x200 pixels…
Bitmap: 2002004bytes = 160.000bytes.
Indexed: 2002001byte + 34bytes = 40.012 bytes.
Example 2: 256 color image 200x200 pixels
Bitmap: 2002004bytes = 160.000bytes.
Indexed: 2002001byte + 2564bytes = 40.768 bytes.
The indexed images were used to save VRAM, at expense of using less colors in the images displayed.
To use more colors the palette must be modified during execution (did you see those fractals with waving colors in a 386??)
In Java exists the IndexedColorModel (it stores the color palette), and a BufferedImage created with this Color Model stores only the indeces in the Raster Data.
I have not found a method in the API to change the color palette… so I don’t know if there is a way to do this effects in Java… :-/
In addition, with the great ammounts of VRAM in the current graphics cards, does not matter if you use RGB images…
Rafael
One effect you can do with images with IndexColorModel is changing the palette of the image, w/o having to re-render it.
Basically, you can create a new BufferedImage with the Raster (pixel data) from the old image and a new IndexColorModel (color data).
But really, these days there’s not much reason to use this image format…
[quote]Basically, you can create a new BufferedImage with the Raster (pixel data) from the old image and a new IndexColorModel (color data).
[/quote]
There is a little problem. If I need to change the palette in each frame (those funky fractals), it requires to create a new BufferedImage (with the new palette) aech time. At 60fps, the ammount of objects created is too big.
I wanted to use palettes as they are used in games like street fighter; one set of sprites (for each fighter) and many palettes for the colors (white ryu, blue ryu, etc.) that the player selected.
Other use is in games like Final Fantasy (8/16 bits era), were the various enemies were the same except for the palette.
Is there a method, to change colors in the IndexColorModel?? This way I make one color change and all the sprites will be updated (not need to create them again).
[quote] Is there a method, to change colors in the IndexColorModel?? This way I make one color change and all the sprites will be updated (not need to create them again).
[/quote]
Keep in mind that unless you are changing the screen palette of a display running in 256 colour mode or less that you will still need to redraw everything. Changing the palette of a sprite will not implicitly effect the display of images already draw to a display.
Back in the days of hardware sprites, where the sprites had a palette that was independant of the display it WOULD work that way… you could animate various things simply by chaning the pallete and you would not have to redraw them to the screen… This was a great advantage in those days because processors were slow, and graphics hardware was fairly primative. Those sort of “tricks” made Commodore Amigas popular with their fancy COPPER (co-processor) designed specifically to change graphics parameters (including palettes and other things) synchronized to the video beam position. It allowed the Amiga to have different palettes and even screen bit depth and resolutions for different bands of the display.
These days everything is so much faster that you can just redraw the entire frame fast enough.
You’ll be creating a new BufferedImage object, but not the raster. BufferedImage instance by itself is not that big, it just holds a reference to a raster and a color model.
[quote]Back in the days of hardware sprites, where the sprites had a palette that was independant of the display it WOULD work that way…
[/quote]
yep, but actually, it can be very helpful to get different sprites at no cost.
trembovetski:
are the palettized bufferedimages transformed to regular bitmap before application, or are they sent as is to the hardware for drawing ?(if they are accelerated, of course)
[quote]One effect you can do with images with IndexColorModel is changing the palette of the image, w/o having to re-render it.
Basically, you can create a new BufferedImage with the Raster (pixel data) from the old image and a new IndexColorModel (color data).
But really, these days there’s not much reason to use this image format…
[/quote]
Well, actually that´s very useful in fighting games, and that´s what I was searching for a long time. I will make some readings about BufferedImages.
Edit:
Okay, this may sound obvious for you, but how do I create a Raster from an existing image…?
[quote] are the palettized bufferedimages transformed to regular bitmap before application, or are they sent as is to the hardware for drawing ?(if they are accelerated, of course)
[/quote]
I’m not sure what do you mean by ‘regular bitmap’.
Only opaque 8-bit managed images are accelerated.
(Note that you’ll get an 8-bit managed mage only if your display depth is 8bit).
The accelerated surface will be rendered using hardware…
There’s a getRaster() method in BufferedImage.
But if your image was created using createImage, the return type will be Image, which doesn’t have getRaster.
You can cast it to a BufferedImage, but it’s not a good practice, as the implementation may change…
I think he´s asking if the Indexed Images are converted to a regular 24/16bit Bitmaps.
And about the getRaster(), the images are created using createImage. I´m finding a way to do that right now.