Page 1 of 1

Insert a BMP image to a Calc

PostPosted: Tue Jul 26, 2011 9:38 am
by Manikandan
Dear all,

I am adding an image to a calc file from vb application and set original size by using the following code. it works fine for EMF type images. But, it does not work for .BMP files. It inserts an image, but it does not set the original size.
Does any one know the solution for this issue ?

Code: Select all   Expand viewCollapse view
Dim oSM As Object
     Dim oDesk As Object
     Dim oDoc As Object
     Dim oSheet As Object
     Dim arg()
     Dim oText As Object
     Dim oGraph As Object, oCursor As Object, DrawPages As Object
     Dim DrawPage As Object, FileURL As String
     Set oSM = CreateObject("com.sun.star.ServiceManager")
     Set oDesk = oSM.createInstance("com.sun.star.frame.Desktop")
     Dim sSize As Object
     Dim sPoint As Object
     Set sSize = oSM.Bridge_GetStruct("com.sun.star.awt.Size")
     Set sPoint = oSM.Bridge_GetStruct("com.sun.star.awt.Point")
     sPoint.X = 0
     sPoint.Y = 0
     sSize.Width = 15500
     sSize.Height = 15500
        Set oDoc = oDesk.loadComponentFromURL("private:factory/scalc", "_blank", 0, arg())
        Set oSheet = oDoc.Sheets.getByIndex(0)
        Set oGraph = oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape")
        ImagefilePath="d:\sample.bmp"
        FileURL = ConvertToUrl(ImagefilePath)
        With oGraph
            .GraphicURL = FileURL
            .Size = sSize
            .Position = sPoint
        End With
        Set DrawPage = oSheet.DrawPage
        Call DrawPage.Add(oGraph)       
        oGraph.setSize (oGraph.Graphic.Size100thMM)

Thanks in Advance.

Regards,

Manikandan

Re: Insert a bmp image to a CALC

PostPosted: Tue Jul 26, 2011 6:09 pm
by Charlie Young
I don't have any particular problem with BMP files. Like I said in the other thread, I did have a problem with the syntax that you said worked for you. I did find that using the property instead of the method worked.

Code: Select all   Expand viewCollapse view
oGraph.Size = oGraph.Graphic.Size100thMM


But I don't see how that could have anything to do with the file type.

As a debugging exercise, you might try writing the sizes (before and after) into cells in your Calc sheet, somewhere out of the way.

Code: Select all   Expand viewCollapse view

        outRange = oSheet.GetCellRangeByName("L1:N2")
        outRange.getCellByPosition(0, 0).setValue(oGraph.Size.Width)
        outRange.getCellByPosition(0, 1).setValue(oGraph.Size.Height)
        outRange.getCellByPosition(1, 0).setValue(oGraph.Graphic.Size100thMM.Width)
        outRange.getCellByPosition(1, 1).setValue(oGraph.Graphic.Size100thMM.Height)
        oGraph.Size = oGraph.Graphic.Size100thMM

        outRange.getCellByPosition(2, 0).setValue(oGraph.Size.Width)
        outRange.getCellByPosition(2, 1).setValue(oGraph.Size.Height)




I also used your ConvertToURL successfully.

Re: Insert a BMP image to a Calc

PostPosted: Thu Jul 28, 2011 8:10 am
by Manikandan
Hi Charlie Young ,

I did the change what you said. No image is displayed and the width & size values shows as 0. why ?
Please help. it is urgent .

Regards,

Manikandan

Re: Insert a BMP image to a Calc

PostPosted: Thu Jul 28, 2011 10:50 am
by rudolfo
Don't make this extra painful for you. First implement this in OOo Basic and test and debug with the OOo IDE and/or MRI and Xray. Once you got it working with OOo Basic you can convert it to the external scripting with Visual Basic.

Re: Insert a BMP image to a Calc

PostPosted: Thu Jul 28, 2011 4:41 pm
by Charlie Young
Manikandan wrote:Hi Charlie Young ,

I did the change what you said. No image is displayed and the width & size values shows as 0. why ?
Please help. it is urgent .

Regards,

Manikandan


I spent some time on this, learning a few things myself.

The Size100thMM property is not available in all cases. I discovered this after trying the "Fit picture in margins" trick I posted in the other thread on different pictures.

The main item of interest using Size100thMM was in setting the original size, but in fitting to the margins only the ratio of height to width is important, and that pops up a division by 0 error, of course. In the case of the Size100thMM property being zeroes, I found that the Graphic.Size property, although MRI showed it to as non-zero, didn't work either. What worked for me was instead of using oGraph.Graphic.Size100thMM, was to back up and use oGraph.Bitmap, though I can't say this will work in all cases.

You can pick your own test image. What I find is if I get something from Google Images, if I do "Save Image As," the problem appears, but if I paste into a graphic editor and save from there, everything is OK.

Don't ask why and don't be shocked. The image I used for testing was the August 5, 1982 cover of Rolling Stone, featuring The Go-Go's in their underwear.

Since I actually share much of Villeroy's disdain for the Basic language, I tried this in c++, where the fit margins looks like

Code: Select all   Expand viewCollapse view
Sequence < ::com::sun::star::beans::PropertyValue > args(2);
   args[0].Name = OUString::createFromAscii("Hidden");
   args[0].Value <<= sal_False;
   args[1].Name = OUString::createFromAscii("MacroExecutionMode");
   args[1].Value <<=  (sal_Int16) 4;
   //get an instance of the spreadsheet
   Reference< XComponent > xcomponent = rComponentLoader->loadComponentFromURL(
      OUString::createFromAscii("private:factory/swriter"),
      OUString::createFromAscii("_blank"),
      0,
      args);
   
   Reference< XTextDocument > rTextDoc (xcomponent, UNO_QUERY);

   Reference< XText > oText = rTextDoc->getText();
   Reference<XStyleFamiliesSupplier> xStyleFamilies(rTextDoc, UNO_QUERY);
   
   Reference< XNameAccess > xNameAccess = xStyleFamilies->getStyleFamilies();
   Reference< XNameContainer > xNameContainer(xNameAccess->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("PageStyles"))), UNO_QUERY);
   Reference< XNameAccess > xNameAccess_2(xNameContainer, UNO_QUERY);
   Reference< XStyle > xStyle(xNameAccess_2->getByName(OUString(RTL_CONSTASCII_USTRINGPARAM("Standard"))), UNO_QUERY);
   Reference< XPropertySet > xPropertySet(xStyle, UNO_QUERY);
   Any aSize = xPropertySet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Size")));
   Any lMargin = xPropertySet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("LeftMargin")));
   Any rMargin = xPropertySet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("RightMargin")));
   
   Size oSize;
   aSize >>= oSize;
   long leftMargin, rightMargin;
   lMargin >>= leftMargin;
   rMargin >>= rightMargin;

   long PageWidth = oSize.Width - leftMargin - rightMargin;
   oSize.Width = PageWidth;
   char URL[2048];
   char *sURL;
   sURL = ConvertToURL(URL,"C:\\Documents and Settings\\Charlie\\My Documents\\gogocoverx.jpg");
   
   Reference<XTextCursor> oCursor = oText->createTextCursor();
   Reference<XMultiServiceFactory> docFactory(xcomponent, UNO_QUERY);   
   Reference<XInterface> GraphicObjectShape = docFactory->createInstance(OUString::createFromAscii("com.sun.star.drawing.GraphicObjectShape"));
   Reference<XShape>  oGraph(GraphicObjectShape, UNO_QUERY);
   Reference< XPropertySet > gShapeProps(oGraph,UNO_QUERY);
   
   Any a;
   OUString aOU = OUString::createFromAscii(sURL);

   a <<= aOU;
   
   gShapeProps->setPropertyValue(OUString::createFromAscii("GraphicURL"),a);
   gShapeProps->setPropertyValue(OUString::createFromAscii("VertOrient"),(Any) (sal_Int8) 1);

   Reference<XTextRange> oCursorRange(oCursor, UNO_QUERY);
   Reference<XTextContent> oGraphContent(oGraph, UNO_QUERY);
   oText->insertTextContent(oCursorRange,oGraphContent,sal_False);
   Reference< XGraphic > oGraphic( gShapeProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Graphic"))), UNO_QUERY );
   Reference< XPropertySet > graphicShapeProps(oGraphic,UNO_QUERY);
   aSize = graphicShapeProps->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Size100thMM")));
   Size gSize;   
   aSize >>= gSize;
   oSize.Height = PageWidth * gSize.Height/gSize.Width;
   oGraph->setSize(oSize);


and a version of ConvertToURL (strfile is the actual filename, URL is just a char array passed for storage allocation).

Code: Select all   Expand viewCollapse view
char *ConvertToURL(char *URL,char *strfile)
{
   long i, j, l;
      
   l = strlen(strfile);

   strcpy_s(URL,2048,"file:///");
   
   j = 8;
   for(i = 0;i < l; i++)
   {
      if(strfile[i] == ' ') {
         strcpy_s(&URL[j],2048,"%20");
         j += 3;
      }
      else  if(strfile[i] == '\\') {
         URL[j] = '/';
         j++;
      }
      else {
         URL[j] = strfile[i];
         j++;
      }
      
   }
   URL[j] = '\0';
   return URL;
}

Re: Insert a BMP image to a Calc

PostPosted: Fri Jul 29, 2011 3:32 am
by Charlie Young
Further news. I don't know what version of VB you are using, but in VB 2010 at least, there are facilities for getting the size information from graphics files independently of OOo.

First, add a reference to System.Drawing (Project > Add Reference).

At the top of your module, put

Code: Select all   Expand viewCollapse view
Imports System.Drawing.Image


Then do

Code: Select all   Expand viewCollapse view
Dim Img As Drawing.Image


and with your FileName variable not converted to a URL, e.g.

Code: Select all   Expand viewCollapse view
FileName = "C:\Documents and Settings\Charlie\My Documents\gogoscovera.jpg"


(This is the problem version of the file)

do

Code: Select all   Expand viewCollapse view
Img = Drawing.Image.FromFile(FileName)


Then there are many properties available.

Img.Height - Height in pixels.
Img.Width - Width in pixels.
Img.VerticalResolution - Pixels per inch
Img.HorizontalResolution - Pixels per inch

With a little arithmetic and a OOo Size struct handy, you can get the original picture size in 1/100th mm.

Code: Select all   Expand viewCollapse view
        oSize.Width = 2540 * Img.Width / Img.HorizontalResolution
        oSize.Height = 2540 * Img.Height / Img.VerticalResolution

        oGraph.Size = oSize


In the margin fitting program, with oSize.Width = PageWidth:

Code: Select all   Expand viewCollapse view
        oSize.Height = PageWidth * Img.Height/Img.Width



Having found that, now I want to be able to do it in VC++, but it seems it is a real horror show implementing the System.Drawing namespace there. Maybe I'll try to write (or find) some function to extract this information from the files.