2010-09-08 105 views
1

找到將圖像置於多重圖像中的函數...但我不確定如何獲取實際圖像寬度(對於單個或多個)並更改_msi.ViewportOrigin x參數基於此。如何在MultiScaleImage中居中圖像

有2線,影響圖像的位置......一個是

_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" /> 
+0

默認縮放將顯示填充控件中所有可用空間的整個圖像。當圖像方面與控件方面不匹配時,你是問如何將垂直或水平居中? – AnthonyWJones 2010-09-08 07:10:34

+0

是的,對於水平方向,當圖像方面與控制方面不匹配時。 – bcm 2010-09-08 10:45:01

+0

(它是一個單一的圖像) – bcm 2010-09-08 11:00:13

回答

2

我同意它是相當混亂,但是使用viewPortWidth和viewPortOrigin你應該能夠做到這一點。

  • 首先,你必須檢查是否ViewPortWidth> 1(這意味着你的形象是目前「窄」就爲父母。如果不是這種情況,您可以檢查是否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並在紙上畫幾張速寫,直到你看着辦吧。

+0

你是男人! – bcm 2010-09-23 23:06:03

+0

如果我的答案能夠真正解決您的問題,請介意獎勵賞金嗎? (這是違反禮儀嗎?) – 2010-09-27 08:42:24

+0

不,我不介意,我認爲這是自動的,直到我收到郵件提醒我這樣做,這是我第一次給予獎勵。 – bcm 2010-09-27 12:12:30