Results 1 to 20 of 20
  1. #1
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default Render an image into a given quadrilateral

    I say quadrilateral and not rectangle because I need the image to be rendered inside of a quadrilateral which does not consist of only right angles. I would like to render an image inside of a quadrilateral defined by four Points. I'm aware I can use Graphics::clip but such a function does not stretch or scale the image. Thanks :)

  2. #2
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,898
    Rep Power
    25

    Default

    What does "render" an image mean? Do you mean draw it on a Graphics context?

  3. #3
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,236
    Rep Power
    7

  4. #4
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default

    Yes I would like it to be drawn onto a graphics context.

    I have looked at the shear and skew of images but I can't figure out how I would use it so that all corners were matched to one of the four points.

    I.e if I have four points, (0,0) (0,1) (1,1) (1, 0) I would expect the image to be stretched(or shrunk) into a 1 by 1 square. I have done this before with a 3D graphics library quite easily by defining two triangles that form the desired quad, map the texture coordinates to their respective vertices and then have the sharder do the rest. However, I don't want to instroduce an entire 3D graphics library for a simple 2d operation.

    Also I don't think I would be able to draw a Trapezoid using shear.

    Thanks :)
    Last edited by JeremyWilms; 08-20-2011 at 04:09 AM.

  5. #5
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,898
    Rep Power
    25

    Default

    Given a normal rectangular image how would its pixels be mapped into the quadrilateral? Would all the pixels go somewhere in the new image, perhaps with some distortion or would some of them be cropped?

  6. #6
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default

    I have done this before with a 3D graphics library quite easily by defining two triangles that form the desired quad, map the texture coordinates to their respective vertices and then have the sharder do the rest. However, I don't want to instroduce an entire 3D graphics library for a simple 2d operation.
    I supposed I'd expect something similar to what the pixel shader does to a texture mapped over a quadrilateral surface.

  7. #7
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,898
    Rep Power
    25

    Default

    Not familiar with pixel shader or texture mapping.

  8. #8
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    I have looked at the shear and skew of images
    What do you mean by "skew" - something other than "shear"? (Genuine question: it's a long time since I studied any geometry!)

    Generally a combination of rotation, enlargement, shear and translation (a so-called affine transformation) will take you from any parallelogram to any other. And there are standard Java methods for that. But you seem to want more than that: you want to transform to a general quadralateral that may or may not be a parallelogram.

    I have done this before with a 3D graphics library quite easily by defining two triangles that form the desired quad
    This seems doable with a pair of affine transformations. The point is that *any* triangle can be seen as half a parallelogram and can, therefore, be mapped via an affine transform to any other triangle.

    I'm not sure, though, that such a transform would be the "prettiest" because a straight line in the source crossing from one of the triangles to the other might well end up "kinked" in the destination. Since you are going from a rectangle (parallel sides) to a thing whose sides are not parallel it looks like you want some sort of projective transformation. A brief google turned up this stackoverflow discussion. Maybe it'll help.
    Last edited by pbrockway2; 08-20-2011 at 04:48 AM.

  9. #9
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

    Default

    Take a look at Java Advanced Imaging's PerspectiveTransform, or if you're free to use JavaFX 2.0 (still in beta) it also has a PerspectiveTransform.

    A perspective transformation is capable of mapping an arbitrary quadrilateral into another arbitrary quadrilateral, while preserving the straightness of lines.
    db

  10. #10
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default

    Thank you pbrockway2, the images I am transforming are rather small and so, at least I hope, it will not be too noticable.

    @DarrylBurke: Thats exactly what I am looking for :) Thanks.

  11. #11
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default

    I can't figure out how to apply a PerspectiveTransform to a graphics object or Image. Do you mind pointing me to a particular example? Thanks.

  12. #12
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

    Default

    Have you gone through the guide? There's a section on Mapping a Quadrilateral.

    db

  13. #13
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default

    Hmm, so it seems I would have to reconstruct the image in another buffer; copying all the pixel data and transforming its position by going via the PerspetiveTransform. Thats doable I guess, are there any other solutions though? It just seems like a lot of post-processing inside of the CPU.

    Thanks.

  14. #14
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    I don't think you are supposed to copy the pixel data and then transform (for one thing the result would be a bit rough - you should really take each pixel of the destination and find the "preimage" pixels in the source and take a weighted average of their colours...). My reading of the docs db pointed to is that you use one of the JAI.create() family to create a rendered image.

    Here's an example using a polnomial warp. The image creation happens in the updateWarp() method where a transformation is created based on user entered points, a parameter block made up using a source image and the transformation, then JAI.create() is called to create the rendered image that actually gets used.

  15. #15
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default

    Ah, sorry, I should've gone through it more thoroughly. I didn't have much time when I was going over it and sort of made the assumption after a quick look at PerspectiveTransform object. Anyway, you have a good point, I really should have looked at the example code.

    Thanks again for your help, and sorry for the confusion.

  16. #16
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    No problem - I had the question as you when I read about the perspective transform: how do you make an image out of the thing?! I think the guide could do with a "tutorial" style commentary (ie some code for us folk in a hurry)

    Darryl will doubtless jump in if I'm putting you wrong, but the code at that link and nearby looks good.

    If JAI.create() works out, post your code: I'd be interested.

  17. #17
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,458
    Rep Power
    20

  18. #18
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default

    I can't quite get this to work.

    Heres the function I've written to wrap the process of creating a warp:
    ;
    m_srcImage is set like so:
    Java Code:
    m_srcImage = = ImageIO.read(new File("C:\\image.png"));
    m_srcImage does draw correctly.
    Java Code:
        public boolean setWarp(Point[] srcPoints, Point[] destPoints)
        {
            if(srcPoints.length != destPoints.length || destPoints.length != 4)
                return false;
            
            float[] src = new float[srcPoints.length * 2];
            float[] dest = new float[destPoints.length * 2];
            
            //Organize points so that they can be applied to JAI warp
            for(int i = 0; i < srcPoints.length; i++)
            {
                src[i * 2] = (float)srcPoints[i].getX();
                src[(i * 2) + 1] = (float)srcPoints[i].getY();
                
                dest[i * 2] = (float)destPoints[i].getX();
                dest[(i * 2) + 1] = (float)destPoints[i].getY();
                
            }
            
            //apply warp to source image.
            WarpPolynomial warp = WarpPolynomial.createWarp(src, 0, dest, 0, 
                                                            srcPoints.length, 
                                                            1, //PrescaleX 
                                                            1, //PrescaleY
                                                            1, //PostScaleX
                                                            1, //PostScaleY 
                                                            1  //Degree
                                                            );
            
            ParameterBlock pb = new ParameterBlock();
            pb.addSource(m_srcImage);
            pb.add(warp);
            pb.add(new InterpolationNearest());
            RenderedOp o = JAI.create("warp", pb);
            m_buildImage = o.getAsBufferedImage();
            return true;
    }
    When drawing m_buildImage I just get a black image(There's no problem in the drawing procedure).

    I call the routine like so:
    Java Code:
    txtu.setWarp(
                             new Point[] {
                                            new Point(0, 0), 
                                            new Point(img.getWidth(null), 0), 
                                            new Point(0, img.getHeight(null)), 
                                            new Point(img.getWidth(null), img.getHeight(null))
                                         }, 
                             new Point[] {
                                            new Point(0, 0), 
                                            new Point(img.getWidth(null), 0), 
                                            new Point(0, img.getHeight(null)), 
                                            new Point(img.getWidth(null), img.getHeight(null))
                                         });
    Thanks, and sorry to load all this code on you.

  19. #19
    JeremyWilms is offline Member
    Join Date
    Aug 2011
    Posts
    9
    Rep Power
    0

    Default

    i missed the WarpPerspective object when I was going through the JAI api. Anyway, I got it working, here it is:

    Java Code:
        public boolean setWarp(Point[] srcPoints, Point[] destPoints)
        {
            if(srcPoints.length != destPoints.length || destPoints.length != 4)
                return false;
            
            //apply warp to source image.
            WarpPerspective warp = new WarpPerspective(
                    PerspectiveTransform.getQuadToQuad(srcPoints[0].x, srcPoints[0].y, //x1, y1 
                                                       srcPoints[1].x, srcPoints[1].y,//x2, y2 
                                                       srcPoints[2].x, srcPoints[2].y,//x3, y3
                                                       srcPoints[3].x, srcPoints[3].y,//x4, y5
                                                       //dest
                                                       destPoints[0].x, destPoints[0].y, //x1, y1 
                                                       destPoints[1].x, destPoints[1].y,//x2, y2 
                                                       destPoints[2].x, destPoints[2].y,//x3, y3
                                                       destPoints[3].x, destPoints[3].y //x4, y5
                                                       ));
            
            ParameterBlock pb = new ParameterBlock();
            
            pb.addSource(m_buildImage);
            pb.add(warp);
            pb.add(new InterpolationNearest());
            
            RenderedOp o = JAI.create("warp", pb);
            m_buildImage = o.getAsBufferedImage();
            return true;
        }

  20. #20
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    I'm glad you've the transformation doing what you want. And thanks for the follow up.

Similar Threads

  1. Replies: 12
    Last Post: 04-14-2011, 02:58 PM
  2. Best Way To Render
    By rp181 in forum Java 2D
    Replies: 1
    Last Post: 03-24-2011, 07:20 PM
  3. Unable to render printing the complete JPanel
    By Y. Progammer in forum New To Java
    Replies: 6
    Last Post: 03-12-2010, 03:18 PM
  4. Why wont my object render properly
    By toecutter in forum AWT / Swing
    Replies: 3
    Last Post: 10-22-2009, 02:43 PM
  5. Loki Render 0.3
    By levent in forum Java Software
    Replies: 0
    Last Post: 07-26-2007, 09:31 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •