2011-01-11 4 views
4

J'utilise le code suivant dans mon site, pour la création des vignettes:Créer miniature dans # .NET C en définissant la largeur

string furl = "~/images/thumbs/" + matchString; 
lBlogThumb.ImageUrl = GetThumbnailView(furl, 200, 200); 


private string GetThumbnailView(string originalImagePath, int height, int width) 
     { 
      //Consider Image is stored at path like "ProductImage\\Product1.jpg" 

      //Now we have created one another folder ProductThumbnail to store thumbnail image of product. 
      //So let name of image be same, just change the FolderName while storing image. 
      string thumbnailImagePath = originalImagePath.Replace("thumbs", "thumbs2"); 
      //If thumbnail Image is not available, generate it. 
      if (!System.IO.File.Exists(Server.MapPath(thumbnailImagePath))) 
      { 
       System.Drawing.Image imThumbnailImage; 
       System.Drawing.Image OriginalImage = System.Drawing.Image.FromFile(Server.MapPath(originalImagePath)); 
       imThumbnailImage = OriginalImage.GetThumbnailImage(width, height, 
          new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero); 

       imThumbnailImage.Save(Server.MapPath(thumbnailImagePath), System.Drawing.Imaging.ImageFormat.Jpeg); 

       imThumbnailImage.Dispose(); 
       OriginalImage.Dispose(); 
      } 
      return thumbnailImagePath; 
     } 

public bool ThumbnailCallback() { return false; } 

Je voudrais changer ce code, et être en mesure de créer une largeur définissant la vignette SEULEMENT. Ce que j'ai à l'esprit est en fait quelque chose comme le recadrage/redimensionnement de l'image, en utilisant une largeur statique, en maintenant son ratio. Est-ce possible;

+1

Est-ce que vous voulez? newHeight = oldHeight * newWidth/oldWidth, vous ne savez pas exactement ce que vous voulez dire quand vous dites que vous voulez recadrer l'image - voulez-vous recadrer ET redimensionner? –

+0

merci pour votre aide – zekia

+0

idk pourquoi mais cela m'a donné un "out of memory" err .. y at-il quelqu'un qui peut mettre une exeption pour cela? Je ne sais pas vraiment comment C# gère la mémoire. –

Répondre

7

avons originalWidth = la largeur et la largeur de l'image d'origine. Vous pouvez simplement choisir le thumbWidth à votre valeur désirée, et calculer le

+0

je vous remercie pour votre aide – zekia

0

Un exemple de base sans arrondi avec une largeur de vignette de 140, ci-dessous le «fichier» est un HttpPostedFile téléchargé à partir d'un contrôle ASP.Net FileUpload, le HttpPostedFile expose un flux.

// Save images to disk. 
using (System.Drawing.Image image = System.Drawing.Image.FromStream(file.InputStream)) 
using (System.Drawing.Image thumbnailImage = image.GetThumbnailImage(140, Convert.ToInt32((image.Height/(image.Width/140))), null, IntPtr.Zero)) 
{ 
    if (image != null) 
    { 
     image.Save(imageFilePath); 
     thumbnailImage.Save(thumbnailImagePath); 
    } 
    else 
     throw new ArgumentNullException("Image stream is null"); 
} 
15

Vous mentionnez le redimensionnement et le recadrage. Si vous voulez que les hauteurs des vignettes varient avec une largeur fixe, les réponses fournies fonctionneront déjà pour vous. La mention de recadrage me fait penser que vous pouvez vouloir une taille de vignette fixe, avec la largeur remplie et toute partie verticale débordante recadrée. Si c'est le cas, vous devrez faire un peu plus de travail. J'avais besoin de quelque chose de similaire récemment, et c'est ce que j'ai trouvé.

Ceci créera une vignette de l'original qui est dimensionnée et rognée de telle sorte que l'image source remplisse complètement la vignette cible, en recadrant tout débordement. Il n'y aura pas de bordures dans la vignette, même si les proportions d'origine et de vignette sont différentes.

public System.Drawing.Image CreateThumbnail(System.Drawing.Image image, Size thumbnailSize) 
{ 
    float scalingRatio = CalculateScalingRatio(image.Size, thumbnailSize); 

    int scaledWidth = (int)Math.Round((float)image.Size.Width * scalingRatio); 
    int scaledHeight = (int)Math.Round((float)image.Size.Height * scalingRatio); 
    int scaledLeft = (thumbnailSize.Width - scaledWidth)/2; 
    int scaledTop = (thumbnailSize.Height - scaledHeight)/2; 

    // For portrait mode, adjust the vertical top of the crop area so that we get more of the top area 
    if (scaledWidth < scaledHeight && scaledHeight > thumbnailSize.Height) 
    { 
     scaledTop = (thumbnailSize.Height - scaledHeight)/4; 
    } 

    Rectangle cropArea = new Rectangle(scaledLeft, scaledTop, scaledWidth, scaledHeight); 

    System.Drawing.Image thumbnail = new Bitmap(thumbnailSize.Width, thumbnailSize.Height); 
    using (Graphics thumbnailGraphics = Graphics.FromImage(thumbnail)) 
    { 
     thumbnailGraphics.CompositingQuality = CompositingQuality.HighQuality; 
     thumbnailGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     thumbnailGraphics.SmoothingMode = SmoothingMode.HighQuality; 
     thumbnailGraphics.DrawImage(image, cropArea); 
    } 
    return thumbnail; 
} 

private float CalculateScalingRatio(Size originalSize, Size targetSize) 
{ 
    float originalAspectRatio = (float)originalSize.Width/(float)originalSize.Height; 
    float targetAspectRatio = (float)targetSize.Width/(float)targetSize.Height; 

    float scalingRatio = 0; 

    if (targetAspectRatio >= originalAspectRatio) 
    { 
     scalingRatio = (float)targetSize.Width/(float)originalSize.Width; 
    } 
    else 
    { 
     scalingRatio = (float)targetSize.Height/(float)originalSize.Height; 
    } 

    return scalingRatio; 
} 

Pour utiliser votre code, vous pouvez remplacer votre appel à OriginalImage.GetThumbnailImage avec ceci:

imThumbnailImage = CreateThumbnail(OriginalImage, new Size(width, height)); 

Notez que pour les images de portrait, ce code changera réellement la fenêtre de la miniature légèrement plus élevé sur l'image originale . Cela a été fait pour que les portraits des gens n'aboutissent pas à des torses sans tête lorsque les vignettes ont été créées. Si vous ne voulez pas cette logique, supprimez simplement le bloc if en suivant le commentaire "mode portrait".

Questions connexes