Insert image size proportional

Hello,

I generates an Excel file with an image inserted in a cell.

I would like this picture keeps its proportional size.

Do you have a solution for me?

Best Regards,

Hi,


What code are you using to insert the image?
I use this: 
ExcelFile.AddImage(FileName,
                    TImageProperties_Create(
                      TClientAnchor.Create(TFlxAnchorType.DontMoveAndDontResize, NumLigne, 0, NumCol, 0, NumLigne+1, 0, NumCol+1, 0),
                        FileName));

This inserts the image into the cell by stretching the image.

I would like a solution that does not stretch the image.
Hi,
You need to specify the anchor by giving the image height/width instead of the ending column and rows:

TClientAnchor.Create(TFlxAnchorType.DontMoveAndDontResize,
          NumLigne, 0, NumCol, 0, Trunc(img.Height), Trunc(img.Width), ExcelFile);

For more information, take a look at:
http://www.tmssoftware.com/site/forum/forum_posts.asp?TID=3763&title=inserting-images-in-sheets
or
This is not what I'm looking. 

I want to copy the image in one and only one cell, with automatic resizing.


Hi,

To do this you still need to use the TClientAnchor overload I mentioned, but you will have to do some extra calculations.

[code]
var
  xls: TExcelFile;
  fs: TFileStream;
  ImgProps: IImageProperties;
  Anchor: TClientAnchor;
  Height, Width: double;
  img: TUIImage;
  
...
  fs := TFileStream.Create('r:\test.png', fmOpenRead or fmShareDenyNone);
  try
    img := TUIImage.FromStream(fs);
    try
      ImgProps := TImageProperties_Create();

      //First create an anchor for the cell, to know the dimensions.
      Anchor := TClientAnchor.Create(TFlxAnchorType.MoveAndDontResize,
          NumLigne, 0, NumCol, 0, NumLigne + 1, 0, NumCol + 1, 0);

      Anchor.CalcImageCoords(Height, Width, xls);
      if img.Width * Height > img.Height * Width  then
      begin //make the image take the full width of the cell, and calculate the height so aspect ratio is 1
        ImgProps.Anchor := TClientAnchor.Create(TFlxAnchorType.MoveAndDontResize,
          NumLigne, 0, NumCol, 0, Trunc(img.Height * Width / img.Width), Trunc(Width), xls);
      end else  //make the image take the full height of the cell, and calculate the width so aspect ratio is 1
      begin
        ImgProps.Anchor := TClientAnchor.Create(TFlxAnchorType.MoveAndDontResize,
          NumLigne, 0, NumCol, 0, Trunc(Height), Trunc(img.Width * Height / img.Height), xls);
      end;

      ImgProps.ShapeName := 'Picture 1';
    finally
      img.Free;
    end;

    fs.Position := 0;
    xls.AddImage(fs, ImgProps);
  finally
    fs.Free;
  end;
[code]


A small remark: The code above will keep the aspect ratio and resize the image so it fits in a whole row or column, but will not center the image. If you also want to center the image in the cell for the dimension that is not the full cell, you could replace the code by this instead:


var
  FinalH, FinalW: double;
...
      if img.Width * Height > img.Height * Width  then
      begin
        FinalH := img.Height * Width / img.Width;
        ImgProps.Anchor := TClientAnchor.Create(TFlxAnchorType.MoveAndDontResize,
          NumLigne, Trunc((Height - FinalH) / 2) , NumCol, 0, Trunc(FinalH), Trunc(Width), xls);
      end else
      begin
        FinalW := img.Width * Height / img.Height;
        ImgProps.Anchor := TClientAnchor.Create(TFlxAnchorType.MoveAndDontResize,
          NumLigne, 0, NumCol, Trunc((Width - FinalW) / 2), Trunc(Height), Trunc(FinalW), xls);
      end;

Thank you for your help. 

After the excel file is generated, is it possible: 

- The image is resized when the cell enlarges?
I tried by putting "MoveAndResize" but it does not work
- Center the image in the cell (height and width) 

3rd request: 
- How to convert pixel size in excel size. 
For the width of a column. 
For the height of a row
>The image is resized when the cell enlarges?
>I tried by putting "MoveAndResize" but it does not work

As far as I know this isn't possible.Move and resize is an Excel option, but only works if you resize a column in the middle of the image. That is, if the image goes from column A to B, and you resize A, it will be resized. But if you resize B, image will stay the same.

This is just how Excel works, we can't do much about it.

> Center the image in the cell (height and width) 
Yes, please look at my post before this one, it shows how to center the image.

> First of all, "pixels" aren't really pixels at all in Excel. We use "device independent pixels" (dip) which are always 1/96 of an inch. For example an image with 1 inch will use 96 physical pixels in a 96 dpi monitor, but to print the same image, you need 1/96*600 actual dots. A dpi is just 1/96 of an inch, in either a monitor or a printer and no matter the actual resolution.

After knowing that, the width of a column in Excel is measured as "how many "0"s you can write in a cell on the normal font". If for example in A1 you can write "00000000" the width is 8. For height, Excel uses points, which are 1/72 of an inch. As a dip is 1/96 of an inch, conversion is simpler than widths.

Now, the easiest way in this case of calculating the dips of the image, is as I showed in the example on my first post:

 //First create an anchor for the cell, to know the dimensions.
      Anchor := TClientAnchor.Create(TFlxAnchorType.MoveAndDontResize,
          NumLigne, 0, NumCol, 0, NumLigne + 1, 0, NumCol + 1, 0);

      Anchor.CalcImageCoords(Height, Width, xls);

Here you create an anchor from row to row + 1, and col to col + 1, and then calculate the height and width of that anchor. This will give you the dips of the cell. I used those in the code to calculate the aspect ratio and to center the image.

If you want, you can also use something like this:
xls.GetColWidth(Col, true) / TExcelMetrics.ColMult(xls) 
and
xls.GetRowHeight(Row, true) / TFlxConsts.RowMult 

for rows. But really, the simplest here is to just create an anchor with the cells, and then read the width and height in dips of that anchor (As I did in the example)


Excellent.
Thank you very much.