Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (526)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (593)
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  
  AffineTransform cuts away parts of my image  (Read 1076 times)
0 Members and 1 Guest are viewing this topic.
Offline johtib

Senior Newbie





« Posted 2004-05-20 07:15:11 »

Hi!

I've written this little tool (http://www.itstud.chalmers.se/~larssont/ImageCreator.zip) to be able to generate rotated versions of an image. The way I'm currently doing the rotation isn't working properly for some reason and I really can't understand why so I'm hoping some of you guys could help me out.

To see what I mean just download and unzip the above file and run the JAR in it.

1. File->Open...
2. Select the image: images/ship_yellow.png
3. Enter the number of frames to generate and click the "Generate" button.

It works with 4 frames but not with 8, the images gets cut of. The source is included in the zip and in the JAR as well. Please have a look at it.

Best Regards,

Johan Tibell

Offline barfy

Junior Devvie




The evidence of things not seen


« Reply #1 - Posted 2004-05-20 10:31:48 »

There are several problems with your image generator:

1. Since the bounds of the image is modified by the rotation, when you call drawImage(source, 0, 0, null) for instance, you can no longer expect the top-left corner of the rotated source image to be at (0, 0) on the destination. Imagine it this way: A plain rectangle image stamped at (20, 0) and then rotated 45 degrees - you get an image whose minimum bounds are less than (20, 0).

Workaround:
Draw the current rotation onto an intermediate image first, then stamp that where you want it to be on the destination.

Example:
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  
public BufferedImage generateRotatedImages(BufferedImage sourceImage, int numFrames)
      {
            // TODO Add support for arbitrary alpha values when Java gets fast enough.
            BufferedImage image = graphicsConfiguration.createCompatibleImage(sourceImage.getWidth()
                        * numFrames, sourceImage.getHeight(), Transparency.BITMASK);
            // An intermediate image to draw a rotated instance of the source image
            BufferedImage rotatedSource = graphicsConfiguration.createCompatibleImage(sourceImage.getWidth(),
                                                                                                                          sourceImage.getHeight(), sourceImage.getColorModel().getTransparency());
           
            Graphics2D g2d = image.createGraphics();
            g2d.setComposite(AlphaComposite.Src);

            // Generate the rotated images.
            int sourceWidth = sourceImage.getWidth();
            int sourceHeight = sourceImage.getHeight();
            double angleBetweenFrames = 2 * Math.PI / numFrames;
            int imageIndex = 0; // the current rotated image index
            for (double a = 0; a < 2 * Math.PI; a += angleBetweenFrames)
            {
                  Graphics2D rsG = rotatedSource.createGraphics();
                  rsG.rotate(a, rotatedSource.getWidth()/2, rotatedSource.getHeight()/2); // set rotation
                  rsG.drawImage(sourceImage, (rotatedSource.getWidth() - sourceWidth)/2, (rotatedSource.getHeight() - sourceHeight)/2, null);

                  g2d.drawImage(rotatedSource, imageIndex * sourceWidth, 0, null); // draw at specified coords

                  rsG.setComposite(AlphaComposite.Clear); // clear the image for use in the next iteration
                  rsG.fillRect(0, 0, rotatedSource.getWidth(), rotatedSource.getHeight());
                  rsG.dispose();
                  imageIndex++; // increment the image index
            }

            g2d.dispose();

            return image;
      }


2. You would still get clipping when the square image is rotated and drawn onto a BufferedImage that is smaller than the size of the rotated image. Imagine a square image that is again rotated 45 degrees (to form a diamond shape) - the bounds of that rotated image is larger than the original, and when drawn onto a destination which is the same size as the square before rotation would result in clipping.

Workaround:
Add a bit of transparent buffer around your sprite image so that the sprite graphic you're interested in doesn't get clipped.

3. You can also consider calling repaint() (as well as revalidate()) on your ImageCanvas whenever the frames are generated. Currently, for 1-4 frames of animation, the ImageCanvas is not updated to draw the generated image.



Offline javazoid

Junior Devvie




Where's Flender?


« Reply #2 - Posted 2004-05-20 11:22:49 »

also take care of interpolation quality issues when rotating/transforming translucent images:

http://developer.java.sun.com/developer/bugParade/bugs/4950176.html

Cheers,

Mik

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

Senior Newbie





« Reply #3 - Posted 2004-05-20 14:24:06 »

Quote
also take care of interpolation quality issues when rotating/transforming translucent images:

http://developer.java.sun.com/developer/bugParade/bugs/4950176.html

Cheers,

Mik


First of all, thanks a bunch both of you, I've almost solved my problems now. Regardsing the workaround you mentioned above I'm not quite sure how to "Using premultiplied image sources (such as INT_ARGB_PRE)", could you provide an example on how to modify the above code to do that?
Offline javazoid

Junior Devvie




Where's Flender?


« Reply #4 - Posted 2004-05-21 05:13:43 »

I have little or no experience with INT_ARG_PRE images. I wrote some test code and I remember it was slower than the INT_ARGB counterpart.
Additionally I had to call coercedata() in order to get something correctly displayed. Maybe I was wrong.

Jim Graham would be of great help for you.

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.

toopeicgaming1999 (71 views)
2014-11-26 15:22:04

toopeicgaming1999 (60 views)
2014-11-26 15:20:36

toopeicgaming1999 (14 views)
2014-11-26 15:20:08

SHC (27 views)
2014-11-25 12:00:59

SHC (25 views)
2014-11-25 11:53:45

Norakomi (31 views)
2014-11-25 11:26:43

Gibbo3771 (25 views)
2014-11-24 19:59:16

trollwarrior1 (38 views)
2014-11-22 12:13:56

xFryIx (77 views)
2014-11-13 12:34:49

digdugdiggy (55 views)
2014-11-12 21:11:50
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

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
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!