Found the function which position the image(s) in the multiscaleimage... but I'm not sure how to get the actual image width (for single or multiple) and change the _msi.ViewportOrigin x param based on that.
There are 2 lines which affect the image position... one is
_msi.ViewportOrigin = new Point(0, 0);
and the other is:
//if (layout == ImageLayout.Vertical) //single column
// X = ((_msi.ViewportWidth - subImages[i].Width) / 2);
I'm ok to change either of which.. but need some help with that.
The code where the above snippets are taken from:
private void ArrangeImagesTile(ImageLayout layout)
{
if (_msi.ActualWidth <= 0 || _msi.ActualHeight <= 0)
return;
_lastMousePos = new Point(0, 0);
_msi.ViewportOrigin = new Point(0, 0);
_msi.ViewportWidth = 1;
Storyboard moveStoryboard = initStoryboard();
double containerAspectRatio = this._msi.ActualWidth / this._msi.ActualHeight;
double spaceBetweenImages = 0.005;
List<SubImage> subImages = new List<SubImage>();
_imagesToShow.ForEach(subImage => subImages.Add(new SubImage(subImage)));
// Capture the total width of all images
double totalImagesWidth = 0.0;
subImages.ForEach(subImage => totalImagesWidth += subImage.Width);
// Calculate the total number of rows required to display all the images
int numRows = 1; // layout - horizontal
if (layout == ImageLayout.One)
numRows = 1; //(int)Math.Sqrt((totalImagesWidth / containerAspectRatio) + 1);
else if (layout == ImageLayout.Four) //.Vertical)
numRows = 2; // subImages.Count;
// Assign images to each row
List<Row> rows = new List<Row>(numRows);
for (int i = 0; i < numRows; i++)
rows.Add(new Row(spaceBetweenImages));
double widthPerRow = totalImagesWidth / numRows;
double imagesWidth = 0;
// Separate the images into rows. The total width of all images in a row should not exceed widthPerRow
for (int i = 0, j = 0; i < numRows; i++, imagesWidth = 0)
{
while (imagesWidth < widthPerRow && j < subImages.Count)
{
rows[i].AddImage(subImages[j]);
subImages[j].RowNum = i;
imagesWidth += subImages[j++].Width;
}
}
// At this point in time the subimage height is 1
// If we assume that the total height is also 1 we need to scale the subimages to fit within a total height of 1
// If the total height is 1, the total width is aspectRatio. Hence (aspectRatio)/(total width of all images in a row) is the scaling factor.
// Added later: take into account spacing between images
rows.ForEach(Row => Row.Scale(containerAspectRatio));
// Calculate the total height, with space between images, of the images across all rows
// Also adjust the colNum for each image
double totalImagesHeight = (numRows - 1) * spaceBetweenImages;
rows.ForEach(Row => totalImagesHeight += Row.Height);
// The totalImagesHeight should not exceed 1.
// if it does, we need to scale all images by a factor of (1 / totalImagesHeight)
if (totalImagesHeight > 1)
{
subImages.ForEach(subImage => subImage.Scale(1 / (totalImagesHeight + spaceBetweenImages)));
totalImagesHeight = (numRows - 1) * spaceBetweenImages;
rows.ForEach(Row => totalImagesHeight += Row.Height);
}
// Calculate the top and bottom margin
double margin = (1 - totalImagesHeight) / 2;
if (_imagesToHide != null)
{
// First hide all the images that should not be displayed
_imagesToHide.ForEach(subImage =>
{
//Do not use opacity for this as it slows down the animation after a few arranges
subImage.ViewportWidth = 0;
});
}
// Then display the displayable images to scale
for (int i = 0; i < _imagesToShow.Count; i++)
{
double X = rows[subImages[i].RowNum].CalcX(subImages[i].ColNum);
//if (layout == ImageLayout.Vertical) //single column
// X = ((_msi.ViewportWidth - subImages[i].Width) / 2);
double Y = margin;
for (int j = 0; j < subImages[i].RowNum; j++)
Y += spaceBetweenImages + rows[j].Height;
_imagesToShow[i].ViewportWidth = containerAspectRatio / subImages[i].Width;
animateImage(moveStoryboard, _imagesToShow[i], new Point(-(X / subImages[i].Width), -(Y / subImages[i].Width))); // for animation, use this statement instead of the next one
_imagesToShow[i].Opacity = 1.0;
}
if (ImagesRearranged != null)
{
ImagesRearranged(this, EventArgs.Empty);
}
// Play Storyboard
moveStoryboard.Begin();
}
Previous Code Reference which goes to the function above when opening the image in msi:
Backend:
private void RootMultiScaleImage_Loaded(object sender, RoutedEventArgs e)
{
// Use the mid point of the image to zoom from
var xx = (MultiScaleImage) sender;
xx.ZoomAboutLogicalPoint(1, 0.5, 0.5);
}
Front-end:
<ControlTemplate x:Key="DeepZoomerControlTemplate" TargetType="zoom:DeepZoomer">
<Grid>
<MultiScaleImage x:Name="RootMultiScaleImage" Loaded="RootMultiScaleImage_Loaded" />