2010-05-18 3 views
2

그래서 내 논리가 결함이와C#의 GDI + 이미지 크기 조정 기능

내가

public void ResizeImageForWeb(string OriginalFile, string NewFile, int MaxWidth, int MaxHeight, int Quality) 
{ 
// Resize Code 

} 

기본적으로이 설정 유사한 기능을 필요로 나는 내 C# 응용 프로그램에서 이미지 크기를 조정하는 더 정확한 방법이 필요합니다, 저는 웹 디자이너가 데스크톱 응용 프로그램을 프로그래밍하지 않으려 고합니다.

+0

int int는 무엇입니까? – SLaks

+0

이미지의 품질, jpg가 압축되는 방법에 대해 1에서 100까지 – Landmine

+0

C# Resize 함수가 아닌 C#으로 작성된 GSI + Resize 함수에 대해 묻고 있습니다. –

답변

0

Google의 빠른 검색은이 작은 것을 찾으십시오. snippet.

+0

이 경우 사용하는 스 니펫입니다. +1. – David

+0

어떻게 그 기능을 사용하여 파일 크기를 더 작게 만들 수 있습니까? – Landmine

+0

@Tyler에서 코드 조각 (Image.GetThumbnailImage, Image.Save)과 동일한 기능을 사용하고 있으므로 동일한 제한 사항이 적용됩니다. –

8

이것은 사용자가 미리보기 이미지를 만들거나 단순히 크기 제한을 적용하기 위해 업로드 한 이미지의 크기를 조정하는 데 사용한 코드입니다. 화질은 다루지 않지만 시작일뿐입니다.

// uses System.Drawing namespace 
public class ImageResizer 
{ 
    public bool ResizeImage(string fullFileName, int maxHeight, int maxWidth) 
    { 
     return this.ResizeImage(fullFileName, maxHeight, maxWidth, fullFileName); 
    } 

    public bool ResizeImage(string fullFileName, int maxHeight, int maxWidth, string newFileName) 
    { 
     using (Image originalImage = Image.FromFile(fullFileName)) 
     { 
      int height = originalImage.Height; 
      int width = originalImage.Width; 
      int newHeight = maxHeight; 
      int newWidth = maxWidth; 

      if (height > maxHeight || width > maxWidth) 
      { 
       if (height > maxHeight) 
       { 
        newHeight = maxHeight; 
        float temp = ((float)width/(float)height) * (float)maxHeight; 
        newWidth = Convert.ToInt32(temp); 

        height = newHeight; 
        width = newWidth; 
       } 

       if (width > maxWidth) 
       { 
        newWidth = maxWidth; 
        float temp = ((float)height/(float)width) * (float)maxWidth; 
        newHeight = Convert.ToInt32(temp); 
       } 

       Image.GetThumbnailImageAbort abort = new Image.GetThumbnailImageAbort(ThumbnailCallback); 
       using (Image resizedImage = originalImage.GetThumbnailImage(newWidth, newHeight, abort, System.IntPtr.Zero)) 
       { 
        resizedImage.Save(newFileName); 
       } 

       return true; 
      } 
      else if (fullFileName != newFileName) 
      { 
       // no resizing necessary, but need to create new file 
       originalImage.Save(newFileName); 
      } 
     } 

     return false; 
    } 

    private bool ThumbnailCallback() 
    { 
     return false; 
    } 
} 
+0

파일 크기를 더 작게 만들 수있는 방법이 800 픽셀 일 때 1.8MB 이미지의 크기를 1MB로 조정합니까? – Landmine

+0

아마도 Save 메서드의 다른 오버로드를 살펴보십시오. http://msdn.microsoft.com/en-us/library/8ex6sdew(v=VS.100).aspx http://msdn.microsoft.com/en-us /library/ytz20d80(v=VS.100).aspx –

+0

화질이 끔찍합니다! 크기 조정은 훌륭하게 작동하지만이 기능은 사용할 수 없습니다. – Landmine

2

Graphics.DrawImage()를 사용하십시오. GetThumbnailImage()는 jpeg 파일에서 120x120 (또는 더 작은) 포함 된 축소판을 반환합니다. 그 크기보다 큰 것은 끔찍할 것입니다.

적절한 설정은 http://nathanaeljones.com/163/20-image-resizing-pitfalls/을 참조하십시오.

4

충격적인 DXT 나 OpenL 등을 사용하지 않고 해상도를 높이면 GetThumbnailImage를 사용하지 않을 것입니다. 많은 Windows 응용 프로그램에서 사용하는 내 자신의 그래픽 라이브러리에서 다음과 같은 것을 사용합니다. 전에 몇 번 공유 했으므로 그물 주위에 변종이 떠있을 수 있습니다.) 여기에는 3 가지 방법이 있습니다. GetNonIndexedPixelFormat 메서드는 처리 할 수없는 픽셀 형식을 전달할 때 GDI 충돌을 막는 데 사용됩니다 (설명에 설명되어 있습니다). 첫 번째 요소는 배율 (배율)로 배율을 조정하고 마지막 배율은 배율을 유지하면서 고정 크기 조정을 허용합니다 (대신 기울이기를 원할 경우 쉽게 수정할 수 있음). 즐기십시오 :

/// <summary> 
    /// Scale Image By A Percentage - Scale Factor between 0 and 1. 
    /// </summary> 
    /// <param name="originalImg">Image: Image to scale</param> 
    /// <param name="ZoomFactor">Float: Sclae Value - 0 to 1 are the usual values</param> 
    /// <returns>Image: Scaled Image</returns> 
    public static Image ScaleByPercent(Image originalImg, float ZoomFactor) 
    {  
     int destWidth = (int)((float)originalImg.Width * ZoomFactor); 
     int destHeight = (int)((float)originalImg.Height * ZoomFactor); 

     Bitmap bmPhoto = new Bitmap(destWidth, destHeight, GetNonIndexedPixelFormat(originalImg)); // PixelFormat.Format24bppRgb); 

     bmPhoto.SetResolution(originalImg.HorizontalResolution, originalImg.VerticalResolution); 

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

     grPhoto.DrawImage(originalImg, 
      new Rectangle(0, 0, destWidth, destHeight), 
      new Rectangle(0, 0, originalImg.Width, originalImg.Height), 
      GraphicsUnit.Pixel); 

     grPhoto.Dispose(); 
     return bmPhoto; 
    } 

    /// <summary> 
    /// Gets the closest non-indexed pixel format 
    /// </summary> 
    /// <param name="originalImage">Image: Original image</param> 
    /// <returns>PixelFormat: Closest non-pixel image format</returns> 
    public static PixelFormat GetNonIndexedPixelFormat(Image originalImage) 
    { 
     /* 
     * These formats cause an error when creating a GDI Graphics Oblect, so must be converted to non Indexed 
     * Error is "A graphics object cannot be created from an image that has an indexed pixel format" 
     * 
      PixelFormat.Undefined 
      PixelFormat.DontCare 
      PixelFormat.1bppIndexed 
      PixelFormat.4bppIndexed 
      PixelFormat.8bppIndexed 
      PixelFormat.16bppGrayScale 
      PixelFormat.16bppARGB1555 
     * 
     * An attempt is made to use the closest (i.e. smallest fitting) format that will hold the palette. 
     */ 

     switch (originalImage.PixelFormat) 
     { 
      case PixelFormat.Undefined: 
       //This is also the same Enumation as PixelFormat.DontCare: 
       return PixelFormat.Format24bppRgb; 
      case PixelFormat.Format1bppIndexed: 
       return PixelFormat.Format16bppRgb555; 
      case PixelFormat.Format4bppIndexed: 
       return PixelFormat.Format16bppRgb555; 
      case PixelFormat.Format8bppIndexed: 
       return PixelFormat.Format16bppRgb555; 
      case PixelFormat.Format16bppGrayScale: 
       return PixelFormat.Format16bppArgb1555; 
      case PixelFormat.Format32bppArgb: 
       return PixelFormat.Format24bppRgb;     
      default: 
       return originalImage.PixelFormat; 
     } 
    } 

    /// <summary> 
    /// Resize image keeping aspect ratio. 
    /// </summary> 
    /// <param name="originalImg">Image: Image to scale</param> 
    /// <param name="Width">Int: Required width in pixels</param> 
    /// <param name="Height">Int: Required height in pixels</param> 
    /// <param name="BackgroundColour">Color: Background colour</param> 
    /// <returns>Image: Scaled Image</returns> 
    public static Image Resize(Image originalImg, int Width, int Height, Color BackgroundColour) 
    { 
     int destX = 0; 
     int destY = 0; 

     float nPercent = 0f; 

     float nPercentW = ((float)Width/(float)originalImg.Width); 
     float nPercentH = ((float)Height/(float)originalImg.Height); 

     if (nPercentH < nPercentW) 
     { 
      nPercent = nPercentH; 
      destX = System.Convert.ToInt16(((float)Width - ((float)originalImg.Width * nPercent))/2f); 
     } 
     else 
     { 
      nPercent = nPercentW; 
      destY = System.Convert.ToInt16(((float)Height - ((float)originalImg.Height * nPercent))/2f); 
     } 

     int destWidth = (int)(originalImg.Width * nPercent); 
     int destHeight = (int)(originalImg.Height * nPercent); 

     Bitmap bmPhoto = new Bitmap(Width, Height, GetNonIndexedPixelFormat(originalImg)); // PixelFormat.Format24bppRgb); 

     bmPhoto.SetResolution(originalImg.HorizontalResolution, originalImg.VerticalResolution); 

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

     grPhoto.DrawImage(originalImg, 
      new Rectangle(destX, destY, destWidth, destHeight), 
      new Rectangle(0, 0, originalImg.Width, originalImg.Height), GraphicsUnit.Pixel); 

     grPhoto.Dispose(); 
     return bmPhoto; 
    } 
+1

+1 여기에 코드를보고하고 시간이 지남에 따라 만료 될 수있는 외부 리소스에 연결하지 않습니다. 사실, 허용 된 대답의 링크가 더 이상 작동하지 않습니다. 감사합니다. – vaitrafra