You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@poi.apache.org by Rob Y <ry...@yahoo.com> on 2008/11/11 22:28:18 UTC

HSSFPicture:getImageDimension fails under eclipse works under AIX

HSSFPicture.resize() uses an internal getImageDimension() method, which uses
various objects from javax.imageio and java.awt.image.  When I call this
method from my AIX C app (via a JNI wrapper), it works.  But to debug my
wrapper, I run it under Eclipse on Windows.  When I call getImageDimension
there, it throws an AritmeticException at the size.width calculation below:

      int[] dpi = getResolution(r);
      size.width = img.getWidth()*96/dpi[0];

it turns out that dpi comes back from getResolution as 0, so you get a
divide-by-zero exception.  Is there a problem using javax.imageio or
java.awt.image under eclipse?  I know eclipse doesn't use AWT normally, but
I'm not getting an 'unable to locate class' type of error.

Thanks,
Rob


Here's the whole method:

    public Dimension getImageDimension(){
        EscherBSERecord bse =
patriarch.sheet.book.getBSERecord(pictureIndex);
        byte[] data = bse.getBlipRecord().getPicturedata();
        int type = bse.getBlipTypeWin32();
        Dimension size = new Dimension();

        switch (type){
            //we can calculate the preferred size only for JPEG and PNG
            //other formats like WMF, EMF and PICT are not supported in Java
            case HSSFWorkbook.PICTURE_TYPE_JPEG:
            case HSSFWorkbook.PICTURE_TYPE_PNG:
            case HSSFWorkbook.PICTURE_TYPE_DIB:
                try {
                    //read the image using javax.imageio.*
                    ImageInputStream iis = ImageIO.createImageInputStream(
new ByteArrayInputStream(data) );
                    Iterator i = ImageIO.getImageReaders( iis );
                    ImageReader r = (ImageReader) i.next();
                    r.setInput( iis );
                    BufferedImage img = r.read(0);

                    int[] dpi = getResolution(r);
                    size.width = img.getWidth()*96/dpi[0];
                    size.height = img.getHeight()*96/dpi[1];

                } catch (IOException e){
                    //silently return if ImageIO failed to read the image
                    log.log(POILogger.WARN, e);
                }

                break;
        }
        return size;
    }
-- 
View this message in context: http://www.nabble.com/HSSFPicture%3AgetImageDimension-fails-under-eclipse-works-under-AIX-tp20448425p20448425.html
Sent from the POI - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: HSSFPicture:getImageDimension fails under eclipse works under AIX

Posted by Rob Y <ry...@yahoo.com>.
Never mind.  I'm testing with 2 jpgs.  Turns out it works with one of them,
so there must be something wrong with the header of the other.  In any case,
it doesn't seem to be an Eclipse-specific error, except that under Eclipse,
it throws the ArithmeticError exception and under AIX, it returns with bogus
dimensions.

Go figure...
-- 
View this message in context: http://www.nabble.com/HSSFPicture%3AgetImageDimension-fails-under-eclipse-works-under-AIX-tp20448425p20449552.html
Sent from the POI - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: HSSFPicture:getImageDimension fails under eclipse works under AIX

Posted by Rob Y <ry...@yahoo.com>.


Rob Y wrote:
> 
> 
> While I was poking around, however, I found a bug in
> HSSFPicture.getPreferredSize().  This line:
> 
>         h += (1 - anchor.dy1/256)* getRowHeightInPixels(anchor.row1);
> 
> doesn't work right.  It computes (1 - anchor.dy1/256) as an integer before
> applying it as a fraction to getRowHeightInPixels.  So you always get h
> incremented by 1 full row height (anchor.dy/256 evaluates to 0).  It works
> if I change it to:
> 
>         h += ((float)1 - (float)anchor.dy1/256)*
> getRowHeightInPixels(anchor.row1);
> 
> Since you said that you were the one that fixed the DPI default problem, I
> figured I'd send this to you so you could apply it whenever you get the
> chance rather than just submitting a bug report.
> 
> 

Same problem with the code to apply an initial x-offset to the image width:

        //space in the leftmost cell
        w += getColumnWidthInPixels(anchor.col1)*(1 - anchor.dx1/1024);

should be:
        w += getColumnWidthInPixels(anchor.col1)*((float)1 -
(float)anchor.dx1/1024);


-- 
View this message in context: http://www.nabble.com/HSSFPicture%3AgetImageDimension-fails-under-eclipse-works-under-AIX-tp20448425p20466994.html
Sent from the POI - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: HSSFPicture:getImageDimension fails under eclipse works under AIX

Posted by Rob Y <ry...@yahoo.com>.

Yegor Kozlov wrote:
> 
> Try 3.2-FINAL.
> 
> A similar issue was reported in bug #45829. Calling HSSFPicture.resize()
> on images that don't specify DPI resulted in a 
> AritmeticException. I fixed it to use default DPI=96 in such cases.
> 
> The fixed version is in 3.2-FINAL:
> http://svn.apache.org/repos/asf/poi/tags/REL_3_2_FINAL/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
> 
> 

As you indicated, switching to 3.2-FINAL fixed my DPI problem.

While I was poking around, however, I found a bug in
HSSFPicture.getPreferredSize().  This line:

        h += (1 - anchor.dy1/256)* getRowHeightInPixels(anchor.row1);

doesn't work right.  It computes (1 - anchor.dy1/256) as an integer before
applying it as a fraction to getRowHeightInPixels.  So you always get h
incremented by 1 full row height (anchor.dy/256 evaluates to 0).  It works
if I change it to:

        h += ((float)1 - (float)anchor.dy1/256)*
getRowHeightInPixels(anchor.row1);

Since you said that you were the one that fixed the DPI default problem, I
figured I'd send this to you so you could apply it whenever you get the
chance rather than just submitting a bug report.

-- 
View this message in context: http://www.nabble.com/HSSFPicture%3AgetImageDimension-fails-under-eclipse-works-under-AIX-tp20448425p20466844.html
Sent from the POI - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: HSSFPicture:getImageDimension fails under eclipse works under AIX

Posted by Rob Y <ry...@yahoo.com>.


> By the way, I made a variant of resize(), called fitToRect(), which takes
> the image dimensions and scales the anchor rectangle so that the image
> will fit without becoming distorted.  Worth submitting?  My only question
> is how to specify the original anchor rectangle.  In my app I use row,
> col, rows and char_widths to specify the original rectangle, but don't
> know that that's the 'natural' choice.  But in any case, it makes more
> sense to fit an image to a rectangle on the spreadsheet than to just
> resize the anchor to the image's natural size.
> 

Hi Yegor.  Thanks for fixing my bug with the (float)'s.

About your 'resize scale factor' change.  I took a slightly different
approach to coding this.  It looks like your resize to scale will do most of
what my approach did, but doesn't really deal with how to figure out the
scale factor.

I coded a 'fit to rectangle' function that figures out the scale factor to
use by figuring out which dimension scales less to match the corresponding
rectangle dimension.  Then, to be nice, it offsets the starting position of
the other dimension so that the resulting scaled image is also centered in
the given rectangle.

My app has to insert a logo image into a designated area in the header of a
spreadsheet, and has to work for different shaped logos (I imagine that's a
common problem).   Again, I'm not sure what is the 'natural' way to specify
a spreadsheet rectangle,  If rows and 'character positions' makes sense, I'd
be glad to submit my function.

Bottom line, though, is that I broke out the code from getPreferredSize that
maps the image size to the crazy XLS anchor parameters into a separate
'setAnchorToRectangle(int row, int col, float width, float height, float
xoffset, float yoffset)' method.  This function maps the crazy anchor
parameters to real world parameters in pixels, and may come in handy in
other places.  getPreferredSize() could just call it.

By the way, is this a reasonable forum to use for this kind of conversation?

-- 
View this message in context: http://www.nabble.com/HSSFPicture%3AgetImageDimension-fails-under-eclipse-works-under-AIX-tp20448425p20531690.html
Sent from the POI - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: HSSFPicture:getImageDimension fails under eclipse works under AIX

Posted by Rob Y <ry...@yahoo.com>.

Yegor Kozlov wrote:
> 
> Try 3.2-FINAL.
> 
> A similar issue was reported in bug #45829. Calling HSSFPicture.resize()
> on images that don't specify DPI resulted in a 
> AritmeticException. I fixed it to use default DPI=96 in such cases.
> 
> 
> The fixed version is in 3.2-FINAL:
> http://svn.apache.org/repos/asf/poi/tags/REL_3_2_FINAL/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
> 

Thanks.  I'll do that.

By the way, I made a variant of resize(), called fitToRect(), which takes
the image dimensions and scales the anchor rectangle so that the image will
fit without becoming distorted.  Worth submitting?  My only question is how
to specify the original anchor rectangle.  In my app I use row, col, rows
and char_widths to specify the original rectangle, but don't know that
that's the 'natural' choice.  But in any case, it makes more sense to fit an
image to a rectangle on the spreadsheet than to just resize the anchor to
the image's natural size.


-- 
View this message in context: http://www.nabble.com/HSSFPicture%3AgetImageDimension-fails-under-eclipse-works-under-AIX-tp20448425p20462685.html
Sent from the POI - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: HSSFPicture:getImageDimension fails under eclipse works under AIX

Posted by Yegor Kozlov <ye...@dinom.ru>.
Try 3.2-FINAL.

A similar issue was reported in bug #45829. Calling HSSFPicture.resize() on images that don't specify DPI resulted in a 
AritmeticException. I fixed it to use default DPI=96 in such cases.


The fixed version is in 3.2-FINAL:
http://svn.apache.org/repos/asf/poi/tags/REL_3_2_FINAL/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java


Yegor

> HSSFPicture.resize() uses an internal getImageDimension() method, which uses
> various objects from javax.imageio and java.awt.image.  When I call this
> method from my AIX C app (via a JNI wrapper), it works.  But to debug my
> wrapper, I run it under Eclipse on Windows.  When I call getImageDimension
> there, it throws an AritmeticException at the size.width calculation below:
> 
>       int[] dpi = getResolution(r);
>       size.width = img.getWidth()*96/dpi[0];
> 
> it turns out that dpi comes back from getResolution as 0, so you get a
> divide-by-zero exception.  Is there a problem using javax.imageio or
> java.awt.image under eclipse?  I know eclipse doesn't use AWT normally, but
> I'm not getting an 'unable to locate class' type of error.
> 
> Thanks,
> Rob
> 
> 
> Here's the whole method:
> 
>     public Dimension getImageDimension(){
>         EscherBSERecord bse =
> patriarch.sheet.book.getBSERecord(pictureIndex);
>         byte[] data = bse.getBlipRecord().getPicturedata();
>         int type = bse.getBlipTypeWin32();
>         Dimension size = new Dimension();
> 
>         switch (type){
>             //we can calculate the preferred size only for JPEG and PNG
>             //other formats like WMF, EMF and PICT are not supported in Java
>             case HSSFWorkbook.PICTURE_TYPE_JPEG:
>             case HSSFWorkbook.PICTURE_TYPE_PNG:
>             case HSSFWorkbook.PICTURE_TYPE_DIB:
>                 try {
>                     //read the image using javax.imageio.*
>                     ImageInputStream iis = ImageIO.createImageInputStream(
> new ByteArrayInputStream(data) );
>                     Iterator i = ImageIO.getImageReaders( iis );
>                     ImageReader r = (ImageReader) i.next();
>                     r.setInput( iis );
>                     BufferedImage img = r.read(0);
> 
>                     int[] dpi = getResolution(r);
>                     size.width = img.getWidth()*96/dpi[0];
>                     size.height = img.getHeight()*96/dpi[1];
> 
>                 } catch (IOException e){
>                     //silently return if ImageIO failed to read the image
>                     log.log(POILogger.WARN, e);
>                 }
> 
>                 break;
>         }
>         return size;
>     }


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org


Re: HSSFPicture:getImageDimension fails under eclipse works under AIX

Posted by David Fisher <df...@jmlafferty.com>.
Rob,

Maybe, you'll need to be "headless"

-Djava.awt.headless=true

Yegor has been through this pain. I suggest you try the following  
experiment.

Create an Excel document with an image in the size you want on Windows.

Open the same file on the Mac. Its aspect ratio will be squashed like  
a standard TV expanded onto HDTV. There are all types of effects the  
most important being the size of the default font in the Excel  
Application which is NOT a document setting.

Play with WIndows dpi and see things change.

FYI there is an even sicker trouble with sizing Escher font characters  
within a drawing. Scaling can lead to results you don't expect.

Microsoft in its wisdom only supports font characters in discrete  
pixel sizes in Excel. Scaling is rounded. And then layout is wrong on  
the Mac due to aspect ratio.

Powerpoint also gives goofy effects with device independent and  
dependent display that differs between Mac and Windows and Excel.

Yes, I wish resize was better, you are free to try. That said I've had  
Yegor spend time on these issues several times over the past few years.

Regards,
Dave

On Nov 11, 2008, at 3:28 PM, Rob Y wrote:

>
> HSSFPicture.resize() uses an internal getImageDimension() method,  
> which uses
> various objects from javax.imageio and java.awt.image.  When I call  
> this
> method from my AIX C app (via a JNI wrapper), it works.  But to  
> debug my
> wrapper, I run it under Eclipse on Windows.  When I call  
> getImageDimension
> there, it throws an AritmeticException at the size.width calculation  
> below:
>
>      int[] dpi = getResolution(r);
>      size.width = img.getWidth()*96/dpi[0];
>
> it turns out that dpi comes back from getResolution as 0, so you get a
> divide-by-zero exception.  Is there a problem using javax.imageio or
> java.awt.image under eclipse?  I know eclipse doesn't use AWT  
> normally, but
> I'm not getting an 'unable to locate class' type of error.
>
> Thanks,
> Rob
>
>
> Here's the whole method:
>
>    public Dimension getImageDimension(){
>        EscherBSERecord bse =
> patriarch.sheet.book.getBSERecord(pictureIndex);
>        byte[] data = bse.getBlipRecord().getPicturedata();
>        int type = bse.getBlipTypeWin32();
>        Dimension size = new Dimension();
>
>        switch (type){
>            //we can calculate the preferred size only for JPEG and PNG
>            //other formats like WMF, EMF and PICT are not supported  
> in Java
>            case HSSFWorkbook.PICTURE_TYPE_JPEG:
>            case HSSFWorkbook.PICTURE_TYPE_PNG:
>            case HSSFWorkbook.PICTURE_TYPE_DIB:
>                try {
>                    //read the image using javax.imageio.*
>                    ImageInputStream iis =  
> ImageIO.createImageInputStream(
> new ByteArrayInputStream(data) );
>                    Iterator i = ImageIO.getImageReaders( iis );
>                    ImageReader r = (ImageReader) i.next();
>                    r.setInput( iis );
>                    BufferedImage img = r.read(0);
>
>                    int[] dpi = getResolution(r);
>                    size.width = img.getWidth()*96/dpi[0];
>                    size.height = img.getHeight()*96/dpi[1];
>
>                } catch (IOException e){
>                    //silently return if ImageIO failed to read the  
> image
>                    log.log(POILogger.WARN, e);
>                }
>
>                break;
>        }
>        return size;
>    }
> -- 
> View this message in context: http://www.nabble.com/HSSFPicture%3AgetImageDimension-fails-under-eclipse-works-under-AIX-tp20448425p20448425.html
> Sent from the POI - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
> For additional commands, e-mail: user-help@poi.apache.org
>


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@poi.apache.org
For additional commands, e-mail: user-help@poi.apache.org