2010-09-08 4 views
1

Trouvé la fonction qui positionne l'image (s) dans l'image multi-échelle ... mais je ne suis pas sûr comment obtenir la largeur réelle de l'image (pour simple ou multiple) et changer le _msi.ViewportOrigin x param basé sur cela.Comment centrer l'image dans MultiScaleImage

Il y a 2 lignes qui affectent la position de l'image ... on est

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

et l'autre est:

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

Je suis autorisé à changer ou l'autre .. mais besoin de l'aide avec ça.

Le code où les extraits ci-dessus sont tirées de:

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

précédent Code de référence qui va à la fonction ci-dessus lors de l'ouverture de l'image dans 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" /> 
+0

Le zoom par défaut affichera toute l'image remplissant tout l'espace disponible dans le contrôle. Demandez-vous alors comment centrer soit la verticale ou l'horizontale lorsque l'aspect de l'image ne correspond pas à l'aspect des contrôles? – AnthonyWJones

+0

oui, pour l'horizontale, lorsque l'aspect de l'image ne correspond pas à l'aspect contrôle. – bcm

+0

(et il s'agit d'une seule image) – bcm

Répondre

2

Je suis d'accord que c'est plutôt déroutant, mais en jouant avec viewPortWidth et viewPortOrigin, vous devriez être capable de le faire.

  • D'abord, vous devez vérifier si ViewportWidth est> 1 (cela signifie que votre image est actuellement « plus étroite » en ce qui concerne est parent. Si ce n'est pas le cas, vous pouvez vérifier si ViewPortHeight> 1 (l'image est plus court et vous devez centrer verticalement)

  • En supposant que ViewPortWidth est> 1, c'est-à-dire que vous avez un espace vide sur la droite et que vous souhaitez centrer la fenêtre horizontalement, vous définissez une valeur négative à ViewPortOrigin pour déplacer le vue à droite

Exemple: ViewPortWidth est 3. Cela signifie que votre image remplit 1/3 de la largeur disponible. Vous devez le déplacer vers la droite une fois sa largeur. ViewportOrigin devient (-1, 0).

Un autre exemple: ViewPortWidth est 4. Votre image remplit 1/4 de la largeur disponible. Si vous définissez ViewPortOrigin sur -1,5, la fenêtre est déplacée de 1,5 fois sa largeur vers la droite et se dirige vers le centre.

La formule générale * doit être ViewPortOrigin.x = - (ViewportWidth - 1)/2

Je vous suggère de regarder la doc et dessiner quelques croquis sur papier jusqu'à ce que vous comprendre.

+0

Vous êtes l'homme! – bcm

+0

Pourriez-vous attribuer la prime si ma réponse résout réellement votre problème? (Est-ce contre l'étiquette?) –

+0

non je ne me dérange pas, je pensais que c'était automatique jusqu'à ce que j'ai reçu le courrier me le rappelant, c'est la première fois que je donne une prime. – bcm