2010-08-03 2 views
1

У меня есть класс, который помогает мне изменить размер моих изображений до указанного размера изображения, но проблема связана с размерами файлов выходных изображений - на самом деле это своего рода смешно, но вот незадача:некоторые проблемы с уменьшенными изображениями и их увеличенными размерами файлов в C#

исходное изображение: 800x600 24bit 96dpi размер файла: 82Kb

повторно размер изображения: 466x340 24bit 96dpi размер файла: 366kb

, что я должен делать? есть ли какой-либо сторонний компонент или проект с открытым исходным кодом в соответствии с этой проблемой?

вот мой упомянутый класс:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Drawing.Drawing2D; 


public class imageClass 
{ 
    public enum Dimensions 
    { 
     Width, 
     Height 
    } 
    public enum AnchorPosition 
    { 
     Top, 
     Center, 
     Bottom, 
     Left, 
     Right 
    } 

    public static Image ScaleByPercent(Image imgPhoto, int Percent) 
    { 
     float nPercent = ((float)Percent/100); 

     int sourceWidth = imgPhoto.Width; 
     int sourceHeight = imgPhoto.Height; 
     int sourceX = 0; 
     int sourceY = 0; 

     int destX = 0; 
     int destY = 0; 
     int destWidth = (int)(sourceWidth * nPercent); 
     int destHeight = (int)(sourceHeight * nPercent); 

     Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb); 
     bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); 

     Graphics grPhoto = Graphics.FromImage(bmPhoto); 
     grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic; 

     grPhoto.DrawImage(imgPhoto, 
      new Rectangle(destX, destY, destWidth, destHeight), 
      new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), 
      GraphicsUnit.Pixel); 

     grPhoto.Dispose(); 
     return bmPhoto; 
    } 
    public static Image ConstrainProportions(Image imgPhoto, int Size, Dimensions Dimension) 
    { 
     int sourceWidth = imgPhoto.Width; 
     int sourceHeight = imgPhoto.Height; 
     int sourceX = 0; 
     int sourceY = 0; 
     int destX = 0; 
     int destY = 0; 
     float nPercent = 0; 

     switch (Dimension) 
     { 
      case Dimensions.Width: 
       nPercent = ((float)Size/(float)sourceWidth); 
       break; 
      default: 
       nPercent = ((float)Size/(float)sourceHeight); 
       break; 
     } 

     int destWidth = (int)(sourceWidth * nPercent); 
     int destHeight = (int)(sourceHeight * nPercent); 

     Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb); 
     bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); 

     Graphics grPhoto = Graphics.FromImage(bmPhoto); 
     grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic; 

     grPhoto.DrawImage(imgPhoto, 
     new Rectangle(destX, destY, destWidth, destHeight), 
     new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), 
     GraphicsUnit.Pixel); 

     grPhoto.Dispose(); 
     return bmPhoto; 
    } 

    public static Image FixedSize(Image imgPhoto, int Width, int Height) 
    { 
     int sourceWidth = imgPhoto.Width; 
     int sourceHeight = imgPhoto.Height; 
     int sourceX = 0; 
     int sourceY = 0; 
     int destX = 0; 
     int destY = 0; 

     float nPercent = 0; 
     float nPercentW = 0; 
     float nPercentH = 0; 

     nPercentW = ((float)Width/(float)sourceWidth); 
     nPercentH = ((float)Height/(float)sourceHeight); 

     //if we have to pad the height pad both the top and the bottom 
     //with the difference between the scaled height and the desired height 
     if (nPercentH < nPercentW) 
     { 
      nPercent = nPercentH; 
      destX = (int)((Width - (sourceWidth * nPercent))/2); 
     } 
     else 
     { 
      nPercent = nPercentW; 
      destY = (int)((Height - (sourceHeight * nPercent))/2); 
     } 

     int destWidth = (int)(sourceWidth * nPercent); 
     int destHeight = (int)(sourceHeight * nPercent); 

     Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb); 
     bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); 

     Graphics grPhoto = Graphics.FromImage(bmPhoto); 
     grPhoto.Clear(Color.Red); 
     grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic; 

     grPhoto.DrawImage(imgPhoto, 
      new Rectangle(destX, destY, destWidth, destHeight), 
      new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), 
      GraphicsUnit.Pixel); 

     grPhoto.Dispose(); 
     return bmPhoto; 
    } 

    public static Image Crop(Image imgPhoto, int Width, int Height, AnchorPosition Anchor) 
    { 
     int sourceWidth = imgPhoto.Width; 
     int sourceHeight = imgPhoto.Height; 
     int sourceX = 0; 
     int sourceY = 0; 
     int destX = 0; 
     int destY = 0; 

     float nPercent = 0; 
     float nPercentW = 0; 
     float nPercentH = 0; 

     nPercentW = ((float)Width/(float)sourceWidth); 
     nPercentH = ((float)Height/(float)sourceHeight); 

     if (nPercentH < nPercentW) 
     { 
      nPercent = nPercentW; 
      switch (Anchor) 
      { 
       case AnchorPosition.Top: 
        destY = 0; 
        break; 
       case AnchorPosition.Bottom: 
        destY = (int)(Height - (sourceHeight * nPercent)); 
        break; 
       default: 
        destY = (int)((Height - (sourceHeight * nPercent))/2); 
        break; 
      } 
     } 
     else 
     { 
      nPercent = nPercentH; 
      switch (Anchor) 
      { 
       case AnchorPosition.Left: 
        destX = 0; 
        break; 
       case AnchorPosition.Right: 
        destX = (int)(Width - (sourceWidth * nPercent)); 
        break; 
       default: 
        destX = (int)((Width - (sourceWidth * nPercent))/2); 
        break; 
      } 
     } 

     int destWidth = (int)(sourceWidth * nPercent); 
     int destHeight = (int)(sourceHeight * nPercent); 

     Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb); 
     bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution); 

     Graphics grPhoto = Graphics.FromImage(bmPhoto); 
     grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic; 

     grPhoto.DrawImage(imgPhoto, 
      new Rectangle(destX, destY, destWidth, destHeight), 
      new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), 
      GraphicsUnit.Pixel); 

     grPhoto.Dispose(); 
     return bmPhoto; 
    } 

} 

С уважением.

формата файл я использую: JPEG

+0

Каким форматом изображения являются изображения и какой код вы используете? – Blorgbeard

+0

Если исходное изображение использует какую-то схему сжатия (как это часто бывает с JPG или PNG), и вы не определили какой-либо размер изображения, это очень возможно. Нам нужно увидеть код и узнать типы изображений. – Oded

+0

Используйте 'Image.GetThumbnailImage' и сохраните его в формате с включенным сжатием. –

ответ

2

Это нормальный побочный эффект передискретизации изображения с InterpolationMode установить высокое значение качества, как Bicubic. Это тонко изменяет значения пикселей примерно для каждого пикселя, тем более, что jpeg декомпрессии производит тонкий шум на изображении. Едва видимо человеческому глазу, вполне видимому фильтру повторной выборки. Давая jpeg encoder a много усложняет сжатие изображения. Только начинать с формата без сжатия, например PNG, может улучшить результат.

0

Если вы явно не определяете формат изображения, по умолчанию он будет иметь формат BMP или PNG. Если вы явно укажете ImageFomat.Jpeg, он будет использовать качество = 100, а не качество = 90 (лучшая настройка, без различимых различий). Check out the 28 image resizing pitfalls, если вы не собираетесь use the recommended library for this situation

ImageResizer library

Вы упомянули библиотеку, и да, она существует. В ImageResizer library избегаются все ошибки GDI, по умолчанию - качество = 90, и не происходит утечка памяти или ручек GDI, даже если изображения повреждены. Он также поддерживает автозагрузку, ручной обрезку, изменение размера, поворот и множество других функций. Это проверено временем, проверено на движение и проверено на единицу.

У этого есть 1-строчный API, который очень прост в использовании. Go check it out!