Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (489)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (555)
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  
  does Java2D support transparency for images?  (Read 4441 times)
0 Members and 1 Guest are viewing this topic.
Offline sluimers

Senior Newbie




Java games rock!


« Posted 2003-04-18 07:34:09 »

I tried with png's but instead of transparent it turned up black   Sad.
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #1 - Posted 2003-04-18 10:25:14 »

Quote

does Java2D support transparency for images?


yes it does.

Most likely, you are creating the image incorrectly.

What paint program are you using?

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

Senior Newbie




Java games rock!


« Reply #2 - Posted 2003-04-18 11:52:08 »

GIMP and it's transparent in there
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 #3 - Posted 2003-04-18 14:35:01 »

ok, how are you loading and drawing it?

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 #4 - Posted 2003-04-19 17:36:00 »

I use GIMP all the time to create transparent PNGs for use in my Java 2 programs.. Works perfectly.  I've never had a problem with it.

Offline mill

Junior Member




popcorn freak


« Reply #5 - Posted 2003-04-20 07:52:20 »

here's how i create my images and transparency works
1  
2  
3  
...
new BufferedImage(loadedImage.getWidth(null), loadedImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);
...

Offline sluimers

Senior Newbie




Java games rock!


« Reply #6 - Posted 2003-04-20 10:33:27 »

Thanks, I feel so stupid now. I just forgot the A in ARGB  Grin.
Offline mill

Junior Member




popcorn freak


« Reply #7 - Posted 2003-04-20 13:00:20 »

Smiley

Offline chet

Senior Newbie




Java games rock!


« Reply #8 - Posted 2003-04-23 13:33:38 »

Note that to make the transparent image a "managed image" (sometimes called "automatic image", but "managed" is a more correct and descriptive term...) you currently need to use other API than creating a BufferedImage explicitly.

That is:
 new BufferedImage(...)
will give you just a palin-old BufferedImage, no possibility of acceleration under the hood.  But:
 GraphicsConfiguration.createCompatibleImage(...)
will give you a BufferedImage that we may, depending on various constraints, cache in VRAM and accelerate using the graphics hardware.

Of course, this currently only works for transparent (vs. translucent) images, unless you are using the not-quite-ready-for-prime-time translucency acceleration described by trembovetski in one of these forums.

In some future release, we hope to "manage" all images, no matter how they are created.  But currently, we just hook into specific API calls, such as:
 Component.createImage()
 GraphicsConfig.createCompatibleImage()
 Toolkit.getImage()
 new ImageIcon().getImage()


Chet
Java2D
Offline mill

Junior Member




popcorn freak


« Reply #9 - Posted 2003-04-23 15:25:38 »

yep he's, of course, right.

this extremely long line of code might be better:

1  
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(loadedImage.getWidth(null), loadedImage.getHeight(null), Transparency.BITMASK);

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline mill

Junior Member




popcorn freak


« Reply #10 - Posted 2003-04-23 15:42:29 »

btw, it might not be so good after all Smiley

i get a not so cool java.lang.OutOfMemoryError when loading ~250 images (sprites, backgrounds, etc)

Offline mill

Junior Member




popcorn freak


« Reply #11 - Posted 2003-04-23 15:49:06 »

ahem, i was a bit hasty there hehe

i had written createCompatibleVolatileImage() instead of createCompatibleImage() and thus forcing all of them into vram


Offline chet

Senior Newbie




Java games rock!


« Reply #12 - Posted 2003-04-23 15:50:12 »

I would think that you would get this same error whether you were creating the BufferedImages explicitly (new BufferedImage) or as managed images (createCompatibleImage()); we are essentially doing the same type of thing underneath.  In the managed image case, we may also create a VRAM-cached version of the image, but these cached images do not affect the size of the Java heap.

In any case, if you are having heap-size problems, you might want to increase your heap size when you run Java.  It runs with a default heap size of 64 M on Windows (I believe); maybe try something like:
   java -Xmx128m <class>
or try other values until you get one that works for you.
Also, if you know your heap will grow to that size, then you probably also want to increase the initial heap size to eliminate the performance penalty of the VM growing the heap incrementally:
 java -Xms128m <class>
would start off Java with a heap of 128 megs (I think it starts at 16M by default, but I'm hazy on that detail).

Chet.
Offline mill

Junior Member




popcorn freak


« Reply #13 - Posted 2003-04-24 03:38:31 »

the error only occured with createCompatibleVolatileImage()

Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #14 - Posted 2003-04-24 12:35:43 »

1  
new ImageIcon().getImage() 


lazy! evil!

resist the temptation of the darkside!

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

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #15 - Posted 2003-04-24 12:38:46 »

Quote
yep he's, of course, right.

this extremely long line of code might be better:

1  
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(loadedImage.getWidth(null), loadedImage.getHeight(null), Transparency.BITMASK);



alternatively, (and alot shorter :P)

1  
<someComponent>.getGraphicsConfiguration().createCompatibleImage(width,height,Transparency.BITMASK);

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

Junior Member




popcorn freak


« Reply #16 - Posted 2003-04-24 12:48:18 »

the component has to be visible, right?

Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #17 - Posted 2003-04-24 12:55:13 »

depends what the component is.

Component.getGraphicsConfiguration() says it does this...

Quote

public GraphicsConfiguration getGraphicsConfiguration()Gets the GraphicsConfiguration associated with this Component. If the Component has not been assigned a specific GraphicsConfiguration, the GraphicsConfiguration of the Component object's top-level container is returned. If the Component has been created, but not yet added to a Container, this method returns null.

Returns:
the GraphicsConfiguration used by this Component or null
Since:
1.3


where as Window does this...

Quote

public GraphicsConfiguration getGraphicsConfiguration()This method returns the GraphicsConfiguration used by this Window.

Overrides:
getGraphicsConfiguration in class Component
Returns:
the GraphicsConfiguration used by this Component or null


from what i've found, I don't think a Window has to be visible for it to have a GraphicsConfiguration object associated with it.

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

Junior Member




popcorn freak


« Reply #18 - Posted 2003-04-24 13:00:19 »

it just seems silly to create a Frame object just for the sake of loading an image in a library of convenient methods Smiley


Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #19 - Posted 2003-04-24 13:25:40 »

That wasn't what i was suggesting, you will ordinarily have a Frame onto which you will render your images anyway.

1) create your game Frame.
2) load your images (using either frame.getToolkit().createImage(), or ImageIO.read()
3) copy your loaded images onto acceleratable images (frame.getGraphicsConfiguration().createCompatibleImage() or frame.getGraphicsConfiguration().createcompatibleVolatileImage())

having steps 2) & 3) is wasteful, and hopefully will be combined in 1.4.2 or 1.5.

p.s. I know frame.createImage() returns an acceleratable image, but I prefer not to use this method, as it is asynchronous, messy, and the images returned have an underlying ImageProducer that misbehaves with some of the image manipulation classes.

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

Junior Member




popcorn freak


« Reply #20 - Posted 2003-04-24 15:52:54 »

just out of curiosity, is there anything very wrong with this?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
private Image loadImage(String fileName, Container con, int transparency) {
            logger.loadingImage(getClass(), fileName);

            Image loadedImage = Toolkit.getDefaultToolkit().getImage(fileName);
            Image returnImage = null;

            MediaTracker tracker = new MediaTracker(con);
            tracker.addImage(loadedImage, 0);
            try {
                  tracker.waitForAll();
            }
            catch (InterruptedException e) {
                  logger.error(getClass(), "Error loading image from file: " + fileName);
            }

            returnImage = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(loadedImage.getWidth(null), loadedImage.getHeight(null), transparency);
            returnImage.getGraphics().drawImage(loadedImage, 0, 0, null);

            return returnImage;
      }


EDIT: a typo

Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #21 - Posted 2003-04-24 17:03:41 »

Don't see why not.  It's what my ImageLoader class is currently doing now, except that I force transparency instead of accepting an int for it.  The code, in fact, is virtually identical.

gK

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

Junior Member




popcorn freak


« Reply #22 - Posted 2003-04-24 17:12:24 »

yah i have methods like

1  
2  
3  
public Image loadBitmaskedImage(String fileName) {
            return loadImage(fileName, new Container(), Transparency.BITMASK);
      }


i love small and lots of methods. damn that XP!

Offline chet

Senior Newbie




Java games rock!


« Reply #23 - Posted 2003-04-24 17:46:07 »

Abuse,

Just wanted to clarify something about Component.createImage().  When I said earlier that calls to this method will create managed (acceleratable) images, the method I was actually referring to was Component.createImage(w, h), not createImage(ImageProducer).  This latter method will not produce a managed image and has the asynchronous problems you pointed out.  But the createImage(w,h) version is completely synchronous (we create the image at the time that you call the method) and it creates a managed image.  Note that this method does not support the transparency that you would need in a sprite; for that, you have to call GraphicsConfiguration.createCompatibleImage(w, h, Transparency.BITMASK), as mentioned in various posts above.

Sorry for the confusion; there's just too many ways to create images and it's easy to get them all confused, especially with our current managed image approach of only hooking into some of these methods for acceleration (just a quick hack while we work on the long term solution of being able to accelerate any image, no matter how it is created).

Chet.
Java2D
Offline Abuse

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #24 - Posted 2003-04-24 21:50:12 »

Quote
Abuse,

Just wanted to clarify something about Component.createImage().  When I said earlier that calls to this method will create managed (acceleratable) images, the method I was actually referring to was Component.createImage(w, h), not createImage(ImageProducer).  This latter method will not produce a managed image and has the asynchronous problems you pointed out.  But the createImage(w,h) version is completely synchronous (we create the image at the time that you call the method) and it creates a managed image.  Note that this method does not support the transparency that you would need in a sprite; for that, you have to call GraphicsConfiguration.createCompatibleImage(w, h, Transparency.BITMASK), as mentioned in various posts above.

Sorry for the confusion; there's just too many ways to create images and it's easy to get them all confused, especially with our current managed image approach of only hooking into some of these methods for acceleration (just a quick hack while we work on the long term solution of being able to accelerate any image, no matter how it is created).

Chet.
Java2D


hehe, my mistake, Cheesy

The line you seem to have picked up on

1  
frame.createImage()


was meant to read

1  
toolkit.createImage()

(which makes what I said immediately after, make alot more sense Cheesy)

as for component.createImage(<any of them>)

I'v already stopped using them in favor of the equivalent GraphicsConfiguration methods.

but I gotta agree, there are way way to many ways to create images  Shocked

maybe for 1.4.2 some1 should go on a deprecation run  Wink

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

JGO Knight


Medals: 12


falling into the abyss of reality


« Reply #25 - Posted 2003-04-24 22:18:54 »

Quote
just out of curiosity, is there anything very wrong with this?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
private Image loadImage(String fileName, Container con, int transparency) {
            logger.loadingImage(getClass(), fileName);

            Image loadedImage = Toolkit.getDefaultToolkit().getImage(fileName);
            Image returnImage = null;

            MediaTracker tracker = new MediaTracker(con);
            tracker.addImage(loadedImage, 0);
            try {
                  tracker.waitForAll();
            }
            catch (InterruptedException e) {
                  logger.error(getClass(), "Error loading image from file: " + fileName);
            }

            returnImage = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(loadedImage.getWidth(null), loadedImage.getHeight(null), transparency);
            returnImage.getGraphics().drawImage(loadedImage, 0, 0, null);

            return returnImage;
      }


EDIT: a typo


well, you've assumed the target machine only has 1 monitor, and 1 video device.

1  
            Image loadedImage = Toolkit.getDefaultToolkit().getImage(fileName);


should realy read

1  
            Image loadedImage = con.getToolkit().getImage(fileName);


and actually, the Toolkit class recommends that developers don't use the toolkit.getImage() either, and instead use the createImage version. (and implement their own caching system)
so, I would say this is most correct :-

1  
            Image loadedImage = con.getToolkit().createImage(fileName);


The same goes for
1  
            returnImage = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice ().getDefaultConfiguration().createCompatibleImage(loadedImage.getWidth( null), loadedImage.getHeight(null), transparency);


you are assuming the default screen device, and default GraphicsConfiguration for that device. (hence the 'compatible' Image returned may not infact be 'compatible' for the Frame on which you intend to render the image!

So, i'd say the line should look like :-

1  
            returnImage = con.getGraphicsConfiguration().createCompatibleImage(loadedImage.getWidth( null), loadedImage.getHeight(null), transparency);


ofcourse for that line to work, you'd also have to change the definition of the method, so 'con' was actually a Frame rather than just a Container.
(but it would make more sense passing in a Frame anyway :-
What You want to load (String, would be better as an URL)
Where you intend to render it (The Frame)
How you intend to render it (The transparency type))

P.S.

I was just thinking about the implications of using toolkit.getImage() on a system with multiple display devices (with regard to how the 'managed image' version of image would be handled

heres abit of code explaining what I mean :-

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
Image fred = getTookit().getImage("fred.png");
Image fred2 = getTookit().getImage("fred.png");
//at this point both fred and fred2 (although different objects) may have the same ImageProducer

GraphicsConfiguration gc1 = <a GraphicsConfiguration for device 1>;
GraphicsConfiguration gc2 = <a GraphicsConfiguration for device 2>;
//2 Graphics Configurations for 2 different devices.

Frame f1 = new Frame(gc1);
Frame f2 = new Frame(gc2);
//The 2 destination Frames (displayed on different screen devices)

f1.show();
f2.show();

f1.getGraphics().drawImage(fred);
f2.getGraphics().drawImage(fred2);
// ^ ok, you would need more than 1 draw for the image to be cached in VRAM,
// but, heres my question...
// how would they be cached :S


in that example, how would the automatic images be managed?
2 images sharing the same ImageProducer, while being rendered to 2 different display devices (and hence requiring 2 different VRam copies [potencially in different pixel formats?]) could cause an awful mess, could it not??

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 #26 - Posted 2003-04-26 04:20:52 »

Abuse,

You reacted pretty strongly to the ImageIcon.getImage() above, calling it lazy and evil.

I'd like to know why, and I'd like to know what your suggestion for a non-lazy version would be.

(Please don't take offense at my question, I'm REALLY REALLY tired and perhaps not phrasing it correctly, but also really interested in the answer.  Why is it evil???)

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 #27 - Posted 2003-04-26 23:43:10 »

Quote
Abuse,

You reacted pretty strongly to the ImageIcon.getImage() above, calling it lazy and evil.

I'd like to know why, and I'd like to know what your suggestion for a non-lazy version would be.


cos its horribly inefficient, if you go through the sourcecode, you'll find that the little line...
1  
new ImageIcon(String).getImage();

hides a huge amount of unnecessary code.

1) you create an ImageIcon,

If its your first ImageIcon, then the following static stuff is created...

A) a MediaTracker
1  
protected final static MediaTracker tracker = new MediaTracker(component);


B) and, because a MediaTracker needs an ImageObserver to monitor the loading, a Component is also created to pass into the MediaTrackers constructor.

1  
protected final static Component component = new Component() {};


neither of those objects will ever become disposable (until the Class Loader is destroyed...),
so by simply creating an ImageIcon, you add an extra overhead to your mem. requirements.

2) ImageIcon uses the toolkit.getImage() variants of the image loading methods rather than createImage(). I don't know if that is good/bad/indifferent, but, it could potencially introduce some problems.

3) MediaTracker itself contains all sorts of rubbish.
For instance, each image added has a 'MediaEntry' object created, which as far as i can gather is simply a node for a linkedlist.
(actually, 'cos its an image, it uses the subclass 'ImageMediaEntry'!!)

there are 2 alternatives,

1) the quick and ez path, use ImageIO Cheesy

2) use toolkit.createImage, toolkit.prepareImage, and an ImageObserver of your own.

Quote

(Please don't take offense at my question, I'm REALLY REALLY tired and perhaps not phrasing it correctly, but also really interested in the answer.  Why is it evil???)


So am I Wink
I always start bitching about Sun code when I get tired  Roll Eyes

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
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.

Nickropheliac (14 views)
2014-08-31 22:59:12

TehJavaDev (23 views)
2014-08-28 18:26:30

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

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

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

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

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

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

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

BurntPizza (48 views)
2014-08-09 21:09:32
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!