Site icon bVisual

Swapping Images in a Visio Shape

I often include images in Visio diagrams, and sometimes they are part of a group shape. There are times when I need to swap the image for another, and I want the correct width to height ratio for the new image to be applied, otherwise the image will be distorted. I recently realised that the Shape.ChangePicture() function in Visio actually returns this ratio which can then be applied to the shape cells so that the image is not distorted. Therefore I wrote some C# code (in LinqPad) to utilize this method to provide the option to change the image in a selected shape or sub-shape.

So, I wrote this function in C# to swap the image of the shape, and to apply the formulas to maintain its correct aspect ratio, even if the shape is subsequently resized.

private void ChangeImage(Visio.Shape shp, string fileName)
{
 //The width:height ratio of the original image is returned
 var imgWHRatio = shp.ChangePicture(fileName);
 //If imgWHRatio > 1 then Landscape else Portrait
 var sect =(short) Visio.VisSectionIndices.visSectionObject;
 var row = (short) Visio.VisRowIndices.visRowForeign;
 //Set the formulas for the Image Width & Height
 shp.CellsSRC[sect, row, (short)Visio.VisCellIndices.visFrgnImgWidth].FormulaForceU =
 $"=IF((Width/Height)>={imgWHRatio.ToString()},Height*{imgWHRatio.ToString()},Width*1)";
 shp.CellsSRC[sect, row, (short)Visio.VisCellIndices.visFrgnImgHeight].FormulaForceU =
 $"=IF((Width/Height)>={imgWHRatio.ToString()},Height*1,Width/{imgWHRatio.ToString()})";
 //Set the Image Offsets
 shp.CellsSRC[sect,row,(short) Visio.VisCellIndices.visFrgnImgOffsetX].FormulaForceU=
 $"=0.5*(Width-ImgWidth)";
 shp.CellsSRC[sect,row,(short) Visio.VisCellIndices.visFrgnImgOffsetY].FormulaForceU=
 $"=0.5*(Height-ImgHeight)";
}

The above routine applies the settings according to the following illustration:

I called this function with some code that already had the Visio.Application variable vWin set.

 var vWin = vApp.ActiveWindow;
 var vSel = vWin.Selection;
 if (vSel.Count == 0)
 {
  //Check if a sub-selection was made
  vSel.IterationMode = (int)Visio.VisSelectMode.visSelModeSkipSuper;
 }
 //Abort if nothing selected
 if (vSel.Count == 0) return;
 var dialog = new OpenFileDialog();
 dialog.Filter = @"png files (*.png)|*.png|
 jpg files (*.jpg)|*.jpg|
 gif files (*.gif)|*.gif|
 bmp files (*.bmp)|*.bmp|
 All files (*.*)|*.*";
 dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.CommonPictures);
 dialog.Title = "Select an image file";
 //Abort if no image selected
 if (dialog.ShowDialog() != DialogResult.OK) return;
foreach (Visio.Shape shp in vSel)
 {
  if (shp.Type == (short)Visio.VisShapeTypes.visTypeForeignObject)
   ChangeImage(shp, dialog.FileName);
  else
  {
    foreach (Visio.Shape s in shp.Shapes)
    {
     if (s.Type == (short)Visio.VisShapeTypes.visTypeForeignObject)
    {
     ChangeImage(s, dialog.FileName);
    }
   }
  }
 }

 
See Shape ChangePicture method

Exit mobile version