Apply AffineTransform to TexturePaint - java

I would like to know how can I rotate a texture paint with image in java.
Normally it is easy to rotate the Graphics2D g2 object, but I don't want to do that. I also don't want to rotate my shape and do some crazy rotation scales, etc. It will be easy to normally do the drawing and fills with paint while paint itself is scaled, rotated, etc.
I also don't want to create a rotated image and then texturepaint it.
There is a createContext inside the texturepaint class but I don't know how can I use it to rotate the original image.
I hope you understand what I mean by rotating the texture itself nwo :) ?
Thank you.
Edit:
I was playing with Java custom Paint implementation performance issue but there is an issue I cannot handle. When there is an offset to where tiling will be started, it does not start correctly.
Sorry for mixing up the problem.

I decided to create a second shape before transform the canvas, and then rotate it back to match the inverse of the trnsform.
This solved my problem.
try {
this.shape = new Path2D.Double(bx.createInverse().createTransformedShape(shape));
} catch (NoninvertibleTransformException ex) {
}

Related

Drawing images to 4 different points

I have a quadrilateral drawn in Path2D, and I would like for there to be an image on it. More specifically, I am trying to draw an image of my choice to 4 different points on a quadrilateral. In my case, it is a parallelogram. I do not want the image to go over the paralellogram. A better way to see what I am trying to say is to see the screenshot below.
I would like the image to be transformed to fit the green area. Not clipped.
I want the image to be pinned over the green paralellogram. However. I do not want the image to go over into the blue paralellogram, or the white space foe that matter.
So far I have tried
Researching for a way to place images directly onto Path2D.Double() objects. No answer
Rotating the image to fit the paralellogram. Didnt work.
Using AffineTransform in java. Dont get it ;-;
Thanks. I am new to java so do try to be lenient?
One way is to:
create a separate BufferedImage.
Apply a transform to the new image.
Draw your image to that new image.
Use the Shape object for the green area as a clip on the main drawing area
Draw the transformed image onto the main drawing area.
It's been a while since I have done transformations. You may have to set the transformation first and then draw the image after. Transformation has to come first.
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.transform(AffineTransform.getShearInstance(1.0, 0));
g2.drawImage(image, 0, 0, this);
}
Here is a simple example of how transforms work. You will have to spend some time on figuring out what values you need to make it work or if you might need to manually create a transformation matrix yourself.

Swing issue: drawing rectangles over the pdf image and keep their size and positions consistent when zooming in and out

I have a rather pressing question in regards to Swing, which I haven't touched for many years.
I have a code that allows the user to draw different rectangles on the pdf document (contained within JPanel). I draw them, move them, resize them, select them, and even write text on them. What I can't do is to keep them consistent when I zoom the document. As the document gets bigger, the rectangles I've drawn stay at the same position and the same size.
I was wondering if there's a relatively easy logic to track the zooming level and, most importantly, update the rectangles accordingly. I can retrieve zoom factor, it's a float, but, unfortunately, I'm using Rectangle object, which uses int for x, y, height, and width. It will be a hassle to convert it to Rectangle.Float, and I wanted to save it for a last resort.
I've tried to use AffineTransform, but I'm not quite familiar with it, for some reason I'm getting the wrong coordinates for y. Can anyone explain to me:
What's the best way to control the Rectangle object, as the pdf document gets zoomed in and out?
If AffineTransform is the best way, how should I handle it (maybe there's a link to a good explanation, if so - I couldn't find it)?
This is the only issue I've been struggling with and it's getting a bit frustrating now.
To scale using an AffineTransform:
Get the transform T of the Graphics object G
Create an AffineTransform object A
Set the scale of A
Set the transform of the G to A
Draw the shapes
Set the transform of G back to T
Translated into code - assuming scale is the value to scale by:
#Override
protected void paintComponent(Graphics gr){
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
AffineTransform prevTransform = g.getTransform();
AffineTransform at = new AffineTransform(prevTransform);
at.scale(scale, scale);
g.setTransform(at);
g.drawRect(...);
g.setTransform(prevTransform);
}

How can I speed up my Java game's FPS?

I am making a Java game, and the game lags a lot when I paint out the graphics.
The way I am currently painting out the graphics is to make a BufferedImage, get the Graphics2D from it, then do a whole bunch of:
g2d.drawImage(loadedImages.getImage(),x,y,null);
After I print all of the images to the BufferedImage, I paint the BufferedImage to the screen.
There are a lot of images I paint to the BufferedImage. Is there a better way to do this that would speed up the painting time?
I do not know much about graphics and graphic cards. Should I use a graphics card? Should I paint directly to the screen? Should I use something entirely different than drawImage()?
The performance should be good if you're drawing a reasonable amount of images.
Make sure you're not creating new BufferedImages every time you draw to the screen. For example, you might have a Resources singleton in which you manage all of your images so that you only load and unload each image once.
If you really want more performance, you'll want to use OpenGL. See LWJGL, libgdx, or JOGL. You may also want to consider 2D graphics libraries like Slick.
I've found it useful to extend java.awt.Canvas and use
BufferStrategy bs;
void init() {
createBufferStrategy(2);// or 3 for triple-buffering
bs = getBufferStrategy();
}
and then the actual draw() method looks like
void draw() {
Graphics g = bs.getDrawGraphics();
g.drawImage(image, x, y, w, h, null);
// Draw more things here...
// You can also make calls like `myObject.draw(g)` and whatever
// you draw onto `g` within those calls will show up.
bs.show();
g.dispose();
}
This is what I use for drawing a lot of things. And then within each myObject.draw(g) call, there are sometimes multiple other similar calls all chained up. Most often my main draw() method has one or two for loops in it that just say for(Entity e: entities) e.draw(g); or something similar. Then the whole drawing chain is kicked off from there.

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...)

Rotate rectangle on an Image Swing

I have an Image on a JPanel. I'm then drawing a rectangle on top of the image like this:
Graphics2D image = (Graphics2D) g;
image.drawRect(......);
//create image code here.
image.rotate(1.5);
image.drawImage(....);
Problem is that when I rotate the image image.rotate(1.5), the rectangles stay in the same place.
I've tried creating the rectangle before rotating the image and after rotating the image, but both times it fails.
Is there an easy way to make the rectangles also rotate along with the image?
Thanks.
One approach is to rotate the graphics context's affine transform, as shown in this example. In that way, all drawing will be rotated by the same amount.
You might want to try using Rectangle, an implementation of the Rectangle2D class, then use g2d.draw(rectangle). This might be able to get the rotation state from the Graphics2D object better.

Categories