2009-02-06 8 views
1

Je redimensionne les fichiers jpeg en utilisant la méthode Graphics.DrawImage (voir le fragment de code ci-dessous). Quelqu'un peut-il confirmer que cela n'affectera pas la compression de la nouvelle image? J'ai vu this thread, mais je parle spécifiquement de la compression des jpegs.Est-ce que le redimensionnement des images JPEG affecte leur compression?

private byte[] getResizedImage(String url, int newWidth) 
    { 
     Bitmap bmpOut = null; 
     System.IO.MemoryStream outStream = new System.IO.MemoryStream(); 

     //input image is disposable 
     using (Bitmap inputImage = LoadImageFromURL(url)) 
     { 
      ImageFormat format = inputImage.RawFormat; 
      decimal ratio; //ratio old width:new width 
      int newHeight = 0; 

      //*** If the image is smaller than a thumbnail just return it 
      if (inputImage.Width < newWidth) 
       return null; 

      ratio = (decimal)newWidth/inputImage.Width; 
      decimal h = inputImage.Height * ratio; 
      newHeight = (int)h; 

      bmpOut = new Bitmap(newWidth, newHeight); 
      Graphics g = Graphics.FromImage(bmpOut); 
      g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
      // try testing with following options: 
      //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
      //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
      //g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; 
      //g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 

      g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight); 
      g.DrawImage(inputImage, 0, 0, newWidth, newHeight); 
      bmpOut.Save(outStream, getImageFormat(url)); 
     } 

     return outStream.ToArray(); 

    } 

Répondre

5

Les fichiers JPEG ne contiennent aucune valeur de "compression". Lorsque vous les redimensionnez et les enregistrez, ils sont compressés avec la valeur que vous indiquez à votre fonction de sauvegarde. Comme vous ne passez pas de valeur, il utilisera simplement la valeur par défaut pour la bibliothèque.

+0

Bien sûr, j'ai été aveuglé par l'objet Graphics, et j'ai réussi à ignorer Bitmap.Save! Merci. – darasd

0

Dans votre code "HighQualityBicubic" est la compression que vous utilisez. Le redimensionnement à une taille plus petite supprime les détails, mais cela n'a rien à voir avec la compression, cela a juste à faire avec moins de pixels.

0

compression JPEG est lossy - pas toutes les données d'origine est stocké exactement. Si vous comprimez une image au format JPEG et la décompressez, vous ne récupérerez pas l'image originale exacte. Chaque fois que vous compressez et décompressez, vous perdez un peu de qualité.

Pour certaines transformations simples, telles que la rotation d'un fichier JPEG, vous pouvez le faire sans perte avec des programmes tels que jpegtran. Toutefois, pour redimensionner des images, vous ne pouvez pas le faire sans perte. Vous allez certainement dégrader la qualité un peu quand vous faites cela, mais probablement pas beaucoup. Si possible, essayez d'utiliser des images originales sans perte comme source pour l'opération de redimensionnement afin d'obtenir la qualité la plus élevée possible et, si vous concaténez plusieurs opérations de redimensionnement, faites simplement un seul redimensionnement à partir de l'original.

0

Ne confondez pas le format de stockage (JPEG) avec le format que vous utilisez sur l'utilisation de l'objet Graphics. Le format de stockage est compressé, l'objet Graphics fonctionne avec des données décompressées. La méthode LoadImageFromURL décompresse les informations stockées dans le fichier JPEG, vous effectuez votre opération de redimensionnement sur les données décompressées et lorsque vous l'enregistrez dans un fichier JPEG, elle est à nouveau compressée.

Étant donné que la compression JPEG n'est pas sans perte, la qualité de l'image sera réduite chaque fois que vous effectuerez ce processus: Décompressez, mutez, recompressez.

Si je missunderstood votre question: Le facteur de compression que vous utilisez pour enregistrer l'image définie dans votre mal placé le code, il sera donc à une valeur par défaut. Si vous voulez réduire la perte de qualité en économisant avec un petit facteur de compression, vous devez le définir explicitement.

0

Merci à MrZebra qui m'a donné un coup de coude dans la bonne direction. This article démontre assez bien ce qu'il faut faire.

4

Redimensionnement d'une image affecte la compression, si par "compression" vous faites référence à combien de détails peuvent être ajustés en combien de pixels.

L'algorithme de compression JPEG favorise les images floues ou homogènes avec des dégradés et des plages de couleurs plates. Par conséquent, il n'y a pas de corrélation directe entre les dimensions de l'image et la taille du fichier qui en résulte. Ce qui importe le plus est la quantité de détails dans l'image (toutes les images ont été enregistrées au format JPEG avec 80% facteur de perte):

  1. L'original SO logo:

    Original http://magnetiq.com/exports/sologo/original.jpg

    File size: 4,483 bytes

  2. Conserver les dimensions et appliquer un fort flou gaussien:

    Blurred http://magnetiq.com/exports/sologo/blurred.jpg

    File size: 1,578 bytes

  3. Redimensionner l'original à 1/4:

    Shrunk http://magnetiq.com/exports/sologo/shrunk.jpg

    File size: 2,063 bytes

Notez que l'image floue (2), même si elle est 4 fois grand comme le rétréci (3) est plus petit dans la taille de fichier que les deux (1) et (2). Le floutage ajoute de jolis dégradés qui rendent la compression JPEG plus agréable.

La petite image (3), bien qu'elle ne contienne que 1/4 des pixels de l'original (1), ne fait pas 1/4 de la taille du fichier. En effet, la réduction de l'image entraîne des détails plus fins et la compression JPEG n'aime pas cela.

Questions connexes