Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (552)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Image compositing using black/white mask and image  (Read 2930 times)
0 Members and 1 Guest are viewing this topic.
Offline GergisKhan

Junior Member




"C8 H10 N4 O2"


« Posted 2003-05-08 13:47:18 »

I previously wrote a Macromedia Fireworks script to do this, but due to some requirements for tools I need to automate this as a Java process.  I've figured out everything except the critical step and can't seem to understand how to do it.

I have an image, which is 64x64 pixels.  It is an RGB image, no Alpha channel.

I have a second image, which is also 64x64 pixels.  This one is black and white.  

What I need to do is to take the full color image and mask it.  Specifically, black areas of the second image should retain color information from the first one, while white areas of the second image should be transparent (therefore, the destination image is RGBA).

I can't seem to composite them properly and the articles I read at Sun about Advanced Imaging and other articles don't help much.

Any thoughts?  I tried using clipping regions, but can't seem to get an irregular clip region based on color.

Thanks.

Edit:

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #1 - Posted 2003-05-08 16:54:08 »

Is it speed critical?

if not, you can simply subclass RGBImageFilter and add the appropriate behaviour.

something like...
(i've expanded it from a 1 liner, so u can understand it Cheesy)

1  
2  
3  
4  
5  
6  
7  
8  
9  
//get the image pixel
int imgPixel = image.getRGB(x,y);
//get the mask pixel
int maskPixel = mask.getRGB(x,y);
//now, get rid of everything but the blue channel
//and shift the blue channel into the alpha channels sample space.
maskPixel = (maskPixel &0xFF)<<24
//now, merge img and mask pixels and copy them back to the image
image.setRGB(x,y,imgPixel|maskPixel);

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #2 - Posted 2003-05-08 17:02:06 »

I got it now.  Thanks.  This should do the trick JUST fine. Smiley

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline jbanes

JGO Coder


Projects: 1


"Java Games? Incredible! Mr. Incredible, that is!"


« Reply #3 - Posted 2003-05-08 17:37:52 »

Seems Abuse beat me to it. Here's my solution:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.util.*;

import javax.imageio.*;
import javax.swing.*;

public class ImageMasker
{
    public static BufferedImage createTileMask(BufferedImage tile, BufferedImage mask)
    {
        GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
       
        BufferedImage result = gc.createCompatibleImage(tile.getWidth(null), tile.getHeight(null), Transparency.BITMASK);
        BufferedImage temp = gc.createCompatibleImage(tile.getWidth(null), tile.getHeight(null), Transparency.BITMASK);
       
        WritableRaster raster = result.getRaster();
        Raster maskData = mask.getRaster();
        Raster tileData = tile.getRaster();
       
        Graphics g;
       
        int[] pixel = new int[4];
        int width = tile.getWidth(null);
        int height = tile.getHeight(null);
       
        for(int y=0; y<height; y++)
        {
            for(int x=0; x<width; x++)
            {
                pixel = maskData.getPixel(x, y, pixel);
               
                if(pixel[0] == 0)
                {
                    tileData.getPixel(x, y, pixel);
                    pixel[3] = 255;
                    raster.setPixel(x, y, pixel);
                   
                    pixel = tileData.getPixel(x, y, pixel);
                }
            }
        }
       
        result.setData(raster);
       
        g = temp.createGraphics();
        g.drawImage(result, 0, 0, null);
        g.dispose();
       
        return temp;
    }
   
    public static void main(String[] args)
    {
        try
        {
            BufferedImage tile = ImageIO.read(new File("color.jpg"));
            BufferedImage mask = ImageIO.read(new File("bw.jpg"));
            BufferedImage masked = createTileMask(tile, mask);
           
            JFrame frame = new JFrame();
            ImageIcon icon = new ImageIcon(masked);
            JLabel label = new JLabel(icon);
           
            frame.getContentPane().add(label);
            frame.pack();
            frame.setVisible(true);
           
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}


It's inefficient, but it works. BTW, I highly recommend not using JPGs for game images unless you are dealing with photographs. You'll cause all kinds of unpredictable artifacts.

P.S. Anyone know how to get this forum to actually preserve spacing? It keeps mucking with my code.

Java Game Console Project
Last Journal Entry: 12/17/04
Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #4 - Posted 2003-05-08 17:41:29 »

Thanks to the both of you.  For some reason I just could NOT get the idea of having to manipulate the image on the pixel level; I was hung up on some crazy idea that I could just call this magical method that would composite the two images.  Now that I'm past that, it's working to my satisfaction.


JPEGs suck when it comes to any image that isn't continuous tone.  I exclusively use PNGs lately (since that's what Fireworks supports, and since I like PNG anyway).

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #5 - Posted 2003-05-08 21:02:08 »

Quote

JPEGs suck when it comes to any image that isn't continuous tone.  I exclusively use PNGs lately (since that's what Fireworks supports, and since I like PNG anyway).


.png is great, now if only IE would support them properly (full alpha channel instead of single bit) then we'd all be happy. Unfortunatly it looks like the next major version of IE will be with longhorn and so quite a while off (yes its probably on Opera and others, but theres no point in making a site that looks substandard on 80% of peoples machines Embarrassed ).

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #6 - Posted 2003-05-08 21:24:41 »

Good to see you around, Orangy Tang.

I agree with you on the PNG in IE thing, however, I've only been using it for 1-bit alpha.  I don't do anything that really requires multi-channel alpha though I know it can be done. (Though you have just given me a REALLY neat idea for transition tiles).

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #7 - Posted 2003-05-08 21:39:05 »

Quote

I was hung up on some crazy idea that I could just call this magical method that would composite the two images


if the AND and OR composition operations were supported, it would be exactly that ez.

1) Blit the mask with a bitwise AND onto the target.
2) Then using a bitwise OR, blit the image over the top.

I still don't understand why the AND and OR drawing operations arn't supported  Huh

Infact, back when I only knew VB, and wrote stuff using the win32 api, those were the only composition operations I knew of!!

any1 know why java doesn't support them?

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #8 - Posted 2003-05-09 01:55:23 »

Is there REALLY no way to do this with the supported compositing rules?
Perhaps we should file a RFE?  Seems dumb to have that fancy compositing stuff in there and yet we have to resort to manipulating things at the pixel data level.  The compositing stuff could even be accelerated with SIMD instructions under the hood (do the JAI performance packs use SIMD instructions?)

Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #9 - Posted 2003-05-09 02:46:31 »

This took me a while to find, but I think you are right, there is a way to do this in the current rules.  It lies in the java.awt.AlphaComposite class, and so far the BEST explanation I have seen of what it can do is here:
http://www.redbrick.dcu.ie/help/reference/java/2d/display/compositing.html

I have no idea how to use the AlphaComposite class, but it's not a big deal.  I can figure it out later.  Now it's almost 1AM here and time for sleep, while dreaming of data structures.
Cool

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #10 - Posted 2003-05-09 09:25:22 »

all the AlphaCompositing rules deal with compositing the Alpha channel (hence the name Cheesy)

What we need for this particular problem is a ColorCompositing class (and yeah, you don't need to check, it doesn't exist Angry)

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline mattocks

Senior Newbie




Java games rock!


« Reply #11 - Posted 2003-05-11 04:16:44 »

See example 11-12 CompositeEffects.java from the O'Reilly "Java Examples in a Nutshell" book:

http://examples.oreilly.com/jenut2/2nd_edition/

The last effect uses a complex shape for a clipping region.

- Craig
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #12 - Posted 2003-05-11 10:17:26 »

Quote
See example 11-12 CompositeEffects.java from the O'Reilly "Java Examples in a Nutshell" book:

http://examples.oreilly.com/jenut2/2nd_edition/

The last effect uses a complex shape for a clipping region.

- Craig


Hmm, spose you could do it like that...

make your own class that implements the Shape interface, and implement the contains(x,y) method as a simple collision map (using the b&w bitmask as the collision map)

It would then be a simple case of using your BitMaskShape object as the clip shape for your Graphics context.

Thats actually quite a neat solution, and very reusable.
Though its pretty slow. (even slower than the suggestions earier Sad)

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline zingbat

Senior Member




Java games rock!


« Reply #13 - Posted 2003-05-11 12:41:39 »

Have you checked the demos in the jfc/java2d. Click the composition tab and see how it works.

I think the mode you need is SrcAtop or DstAtop.
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #14 - Posted 2003-05-11 15:25:33 »

Quote
Have you checked the demos in the jfc/java2d. Click the composition tab and see how it works.

I think the mode you need is SrcAtop or DstAtop.


that is AlphaCompositing only, it deals with the src and dst Alpha channel, not the pixel color.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #15 - Posted 2003-05-11 15:54:24 »

See reply below: it wasn't showing up well on the white contrast, so I'm double posting just to get it on blue.

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #16 - Posted 2003-05-11 15:57:15 »

I think I need to clarify one thing.

+ =  
Click to Playwww.gergis.net/result.gif"/>


Does tht modify any of the suggestions made so far?  I'm somewhat liking the RGBImageFilter solution myself, but I wanted to post this to see if that might change the AlphaComposite attempted solutions.

Thanks.

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #17 - Posted 2003-05-11 17:26:54 »

Quote


Hmm, spose you could do it like that...

make your own class that implements the Shape interface, and implement the contains(x,y) method as a simple collision map (using the b&w bitmask as the collision map)

It would then be a simple case of using your BitMaskShape object as the clip shape for your Graphics context.

Thats actually quite a neat solution, and very reusable.
Though its pretty slow. (even slower than the suggestions earier Sad)


I tried my earlier idea, and it doesn't work.

setClip uses the PathIterator of the shape for determining 'insideness' of a point, and because the shape described by a bitmask image cannot be represented as a Path, there is no way this idea will work.

It could be done using the the Composite interface , however the Composite interface is fairly complicated, so I aint gonna bother trying Cheesy

As you mentioned, its prolly eziest to stick with the RGBFilter.

Perhaps an RFE is in order. (Something like a ColorComposite or PixelComposite class)

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #18 - Posted 2003-05-11 19:09:34 »

I think the key here is that we need to get an image that is either 1-bit or 8-bit greyscale to be interpreted as an Alpha channel instead of the image colour content.
This might be possible with existing image and compositing classes.

Isn't there a way to make a custom image format where you can say which bits are part of which ARGB component?

The existing AlphaComposite class is fine, as long as we can tell it that the binary or greyscale image is nothing but alpha data.

GK - It looks like you figured this out already, but I will mention it in this thread just for completness.  A white (FF) alpha channel indicates 100% opaque, a black (0) alpha channel indicates 100% transparent.   The images used in this thread are backwards from that standard

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #19 - Posted 2003-05-11 23:23:08 »

I looked into this a bit more.

It looks like the main thing to do is to change the SampleModel of the BufferedImage's Raster so that there is a band for  Alpha.  The BufferedImage's ColorModel would need to change too.  The question is.  Can you make these changes on a BufferedImage and the related classes to remap the data in the Raster?  It would be great if you could do this without needing to copy image data around.
Incidentally, that would be the next step I would try.. copy that mask to the alpha channel of another image when you first load it, then use the built-in AlpahComposite stuff as needed.

Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #20 - Posted 2003-05-12 00:09:49 »

Quote
I looked into this a bit more.

It looks like the main thing to do is to change the SampleModel of the BufferedImage's Raster so that there is a band for  Alpha.  The BufferedImage's ColorModel would need to change too.  The question is.  Can you make these changes on a BufferedImage and the related classes to remap the data in the Raster?  It would be great if you could do this without needing to copy image data around.
Incidentally, that would be the next step I would try.. copy that mask to the alpha channel of another image when you first load it, then use the built-in AlpahComposite stuff as needed.



thats pretty much what was suggested right at the start of this Thread Wink

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #21 - Posted 2003-05-12 02:17:15 »

Well not directly... The earlier talk was about manipulating the pixels manually to put the alpha channel into the foreground image.  I was suggesting that, if there is a reason, it could be kept separate as the alpha channel of some different image.  But when I look closer it seems that it won't work that way either.. since there is no way to give a third image as the alpha channel for the AlphaComposite stuff.

So nevermind Smiley

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CopyableCougar4 (23 views)
2014-08-22 19:31:30

atombrot (34 views)
2014-08-19 09:29:53

Tekkerue (30 views)
2014-08-16 06:45:27

Tekkerue (28 views)
2014-08-16 06:22:17

Tekkerue (18 views)
2014-08-16 06:20:21

Tekkerue (27 views)
2014-08-16 06:12:11

Rayexar (65 views)
2014-08-11 02:49:23

BurntPizza (41 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (41 views)
2014-08-06 19:49:38
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!