代码之家  ›  专栏  ›  技术社区  ›  bcm

如何在多尺度图像中居中

  •  1
  • bcm  · 技术社区  · 15 年前

    找到在多尺度图像中定位图像的函数。。。但我不知道如何获得实际的图像宽度(对于单个或多个)并更改_msi.ViewportOrigin基于这个。

    _msi.ViewportOrigin = new Point(0, 0);
    

    另一个是:

    //if (layout == ImageLayout.Vertical) //single column
    //    X = ((_msi.ViewportWidth - subImages[i].Width) / 2);
    

    我可以改变任何一个。。但我需要一些帮助。

    上述代码片段的来源:

     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();
            }
    

    在msi中打开图像时指向上述函数的上一个代码参考:

    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);
            }
    

    前端:

     <ControlTemplate x:Key="DeepZoomerControlTemplate" TargetType="zoom:DeepZoomer">
                <Grid>
    <MultiScaleImage x:Name="RootMultiScaleImage" Loaded="RootMultiScaleImage_Loaded" />
    
    1 回复  |  直到 15 年前
        1
  •  2
  •   Francesco De Vittori    15 年前

    我同意这是相当混乱的,但是玩viewPortWidth和viewPortOrigin你应该可以做到。

    • 首先,您必须检查ViewPortWidth是否为>1(这意味着您的图像当前相对于is parent“更窄”)。如果不是这样,可以检查ViewPortHeight是否大于1(图像较短,必须垂直居中)。

    • 假设您发现ViewPortWidth为>1,即右侧有空白,并且希望将视口水平居中,则将负值设置为ViewPortOrigin以将视口向右移动。

    例子 :ViewPortWidth为3。这意味着您的图像填充了可用宽度的1/3。你必须把它向右移动一倍宽度。ViewportOrigin变为(-1,0)。

    :ViewPortWidth为4。您的图像填充了可用宽度的1/4。如果将ViewPortOrigin设置为-1.5,则视口实际上会向右移动其宽度的1.5倍,并实际移动到中心。

    通式* 应为ViewPortOrigin.x=-(ViewPortWidth-1)/2

    doc 在纸上画些素描,直到你明白为止。