Drawing a Translucent .png in AWT - java

I'm trying to draw a transparent.png image over a TV signal (so blending before rendering is kinda out).
When I was drawing a transparent rect, I could just set SrcOver and specify an alpha for my background color and it would work:
((DVBGraphics) g).setDVBComposite(DVBAlphaComposite.SrcOver);
But now I'm actually trying to use a png with transparency set and that doesn't work (it's just solid).
If I set XOR mode:
g.setXORMode(Color.white);
after setting SrcOver, the entire image becomes translucent, not just the specified dots. Also the parts set to "Transparent" are still visible.
Can anyone point me to the magic set of calls that makes this work?
(Also, swing isn't available--just most of java 1.4).

I can only suggest you recheck everything; I have painted PNG images using AWT before and it worked fine, just doing the obvious:
private final Image image; //
protected void paintForeground(Graphics2D gc, int wid, int hgt) {
...
gc.drawImage(image,dx,dy,(dx+width),(dy+height),0,0,width,height,null);
...
}
This paints with the image transparency honored, except on J2ME 1.1 platforms.
Drawing mode is normal paint, not XOR.

Related

Java zoom in on hi-res image without pixelation or losing drawing

I'm using the approach I found in this answer to create zoom in/out functionality for an image labeling application. However, despite dealing with relatively high resolution images (order of 1500x1500 pixels), the scaling method for zoom leads to pixelation. I checked the image in Windows Photo Viewer and I could definitely zoom in without much pixelation until much more than the 200% zoom I have in my code.
If I resize only compared to the original image (i.e. not cascading each resize call), this works just fine (this is what's in the code snippet). But in order to do this, I lose any drawing functionality. Basically, I would like to be able to do the following:
Load an image
Draw lines/circles/shapes/etc on it
Zoom in (maintaining any drawing on the image)
Draw more
Zoom in/out at will for whatever reasons I need
In summary, the resizing-for-zoom works. It's preserving any additional drawing at each stage of the zoom that I can't seem to get.
Here's a code snippet of my resize function (heavily influenced by that answer cited before):
private void resizeImage()
{
int newImgW = (int)(this.zoom * this.imgW);
int newImgH = (int)(this.zoom * this.imgH);
BufferedImage resized = new BufferedImage(newImgW, newImgH, originalImage.getType());
graphics2D = resized.createGraphics();
graphics2D.drawImage(this.originalImage, 0, 0, newImgW, newImgH, null);
this.image = resized;
repaint();
}

Java Animated transparent splash screen

I'd like to make a splash screen with an animated gif. My animated gif has a transparent background so I'd like to display only the visible part of my gif as a splash screen.
First of all, I must specify that I'm using Matlab so it is not possible (or I haven't found how) to override components/functions.
Here my sample code :
win = javax.swing.JWindow;
jl = javax.swing.JLabel(javax.swing.ImageIcon('C:\Users\ME\Documents\loader512-.gif'));
win.getContentPane.add(jl);
win.setAlwaysOnTop(true);
win.pack;
%% set the splash image to the center of the screen
screenSize = win.getToolkit.getScreenSize;
screenHeight = screenSize.height;
screenWidth = screenSize.width;
% get the actual splashImage size
imgHeight = 512;
imgWidth = 512;
win.setLocation((screenWidth-imgWidth)/2,(screenHeight-imgHeight)/2);
win.show
It works very well shwing the image, however its background is ether white or gray depending on the transparency of the window.
I also tried to play with the background of the JLabel without success.
Please help !
The problem with your code is that every given window has a particular defined shape. Without changing the shape every Window object has a rectangular canvas in which it draws upon. The transparency only applies if you draw a object behind your GIF image. If transparency is enabled the renderer merely draws the background colour (which is normally black or white or some light gray) if nothing else is present.
Since the release of Java 7 a new method called setShape(Shape); appeared for Window objects. If your animated GIF has a fixed transparency "zone" I advise creating a custom java.awt.Shape object in which you pass to the win object via set shape.
Example:
win = javax.swing.JWindow;
jl = javax.swing.JLabel(javax.swing.ImageIcon('C:\Users\ME\Documents\loader512-.gif'));
win.getContentPane.add(jl);
Shape S = createCustomShape(); //Create your shape
win.setShape(S);
win.setAlwaysOnTop(true);
//{rest of code...}
If the animated GIF has a changing transparency background, you must create a complex implementation in which the Shape object updates on a frame by frame basis in response to the GIF. In my opinion, if this is the case, I wouldn't bother. :)
Read more on the Shape object here.
N.B. The Shape "object" is actually a interface, either use one of the implementing subclasses or create your own.

Transparency in texture not working in libgdx

I'm trying to draw a sprite in libgdx that has a transparent background to it, but the transparent background is filled in with white instead of showing what has already been rendered at that location.
The sprite (with the hat) is 64 by 64 with transparency around the edge and on the right. There should be two tiles with a 'C!' behind him but it's just filled in with white.
This is the code I am using to render the image.
public void draw(SpriteBatch sb, float parentAlpha){
sb.enableBlending();
sb.draw(texture, getX() + 32, getY());
}
If you're going to enable blending, you also need to set the blend function with setBlendFunction. This defines exactly how you want the blending to work. Presumably, you want the classic GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA blending.
All the sprites are supposed to be blended? Maybe disabling the blend after you already drawn could solve your problem.
Maybe something like that:
public void draw(SpriteBatch sb, float parentAlpha){
sb.enableBlending();
sb.draw(texture, getX() + 32, getY());
sb.disableBlending();
}
If this doesn't work you could try activating the blend in the GL options with something like that:
Gdx.gl.glEnable(GL10.GL_BLEND);
Gdx.gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
...
Your code Here
...
Gdx.gl.glDisable(GL10.GL_BLEND);
Hope it helps :)
First, make sure your PNG has transparency information in it.
Second, make sure you're drawing things in the right order (you have to draw the background boxes before the sprite).
I managed to fix the problem by changing my application to OpenGL 2.0 instead of 1.0. Still not sure what the problem was.

ToolTip for own drawings

my java application contains a JPanel on which I draw certain shapes. Now I would like to label these shapes with some kind of tooltips.
Therefore I tried to create my own "Tooltips" by using the drawString, setBackground, setColor method.:
public void drawToolTip(Graphics2D graphics, String text, Point2D position) {
graphics.setBackground(Color.RED);
graphics.setColor(Color.GREEN);
graphics.drawString(text, (float) position.getX(), (float) position.getY());
}
Unfortunately the setBackground method does not seem to work. The text background remains transparent although I set it to red. setColor and drawString just work fine.
My questions are:
What could be the reason that the setBackground method does not work?
Is there a possibility to draw a boarder arround the text without drawRect?
If I want to use "drawRect" method as a substitude to draw the text background and border: How can I make it automatically fit to the written text? Or in other words how can I get the dimensions of a specific text?
Regards Marc
Graphics2D.drawString() does not draw a background by default. You will have to do this yourself.
You can use drawRect() to draw a line border or fillRec() to draw a solid rectangle.
Oracle has a great tutorial on measuring String widths. Essentially, you need to create a java.awt.Font then get its FontMetrics and use that to calculate the width and height of your string.
A simple implementation would involve drawing onto the Graphics object of a JLabel's icon. And then simply adding the tool tip text to the Swing component.
For more information, see How to Use Tool Tips.
You can not change background color the way you expect using graphics.setBackground(..) call. Setting background color in the Graphics2D only affects the clearRect or fillRect kind of calls and not the background color of the Component.
For drawing a rectangle at a location you wish, with specific back ground, you will have to relay on following steps:
Define a rectangle - r
grpahics.setPaint() for background and
graphics.fill(r) graphcis.setPaint() for border and
graphics.draw(r) to draw border
now, comes the difficult part of drawing text in to the rectangle which involves computation of height etc. based on FontMetrics of the font you would set for drawing the text.
I googled and found an example for you here

Can we tilt a JPanel at an angle?

I have image inside the JPanel. I would like to rotate the image. Is it possible to rotate the JPanel using Graphics, Image is rotatable, Just out of curiosity is it possible to rotate JPanel ?
Yes! This is possible and fairly straightforward too. I haven't done rotations but I have done other affine transformations (scaling the entire GUI up and down) very successfully on a project. I cannot see why rotations should be any different.
Instead of trying to scale each component use the fact that you can set a transformation on the Graphics object. Since this is shared between all components being rendered you get all things transformed at once "for free". It is important to realize that the transformation is only a rendering-process-step ... i.e. all components still believe they have the bounds (locations+sizes) which you gave them in the untransformed world. This leaves us with the challenge to deal with mouse-events correctly. To do this you simply add a glass-pane in front of your main-panel. This pane collects all mouse-events and apply a reverse of the transform on the event and then sends the event onward towards all other components.
Conceptually very simple! Still, I remember it took some tweaking to get it all crisp though. Especially the fact that rendered texts (fonts) in java are not correctly linearly scaled (it scales in discrete steps corresponding to font-sizes) imposed a final challenge in my scale-affine-transformation-case. Maybe you don't have to worry about that if you only rotate.
I got my inspiration from JXTransformer: http://www.java.net/blog/alexfromsun/archive/2006/07/jxtransformer_t.html
As far as I know you can't rotate a JPanel itself but you might be able to rotate the image inside the JPanel using Java2D. Here's an article that might help.
Edit:
There might actually be a way to rotate JComponents (such as JPanel) if you override their paintXxx methods and use AffineTransform.
It's not possible to rotate JPanel itself, but it's certainly possible to rotate any image inside. There are quite a few ways to do that, you can - for example - override JPanel's public void paint(Graphics g) and then cast Graphics to Graphics2D. It's very useful class, does rotation and much more ;) Check api docs for more info about this one.
Yes, it is possible. But you won't rotate the panel, but the image:
public void paintComponent(Graphics gg)
{
Graphics2D g = (Graphics2D) gg;
g.setRenderingHint(RenderingHints.KEY_ANTI_ALIAS, RenderingHints.VALUE_ANTI_ALIAS_ON);
AfflineTransform matrix = g.getTransform(); // Backup
float angle = Math.PI / 4.0f; // 45°
g.rotate(angle);
/* Begin */
g.drawImage(yourImage, [your coordinates], null);
/* End */
g.setTranform(matrix); // Restore
}
Everything between /* Begin */ and /* End */ will be drawn rotated.
(I didn't test the code, so, they may be some syntax errors...)

Categories