문제

일부 이미지를 사용자의 화면 해상도로 크기를 조정하고 있습니다. 종횡비가 잘못되면 이미지를 잘라야합니다. 내 코드는 다음과 같습니다.

protected void ConvertToBitmap(string filename)
    {
        var origImg = System.Drawing.Image.FromFile(filename);
        var widthDivisor = (double)origImg.Width / (double)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
        var heightDivisor = (double)origImg.Height / (double)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
        int newWidth, newHeight;

        if (widthDivisor < heightDivisor)
        {
            newWidth = (int)((double)origImg.Width / widthDivisor);
            newHeight = (int)((double)origImg.Height / widthDivisor);
        }
        else
        {
            newWidth = (int)((double)origImg.Width / heightDivisor);
            newHeight = (int)((double)origImg.Height / heightDivisor);
        }

         var newImg = origImg.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
        newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
    }

대부분의 경우, 이것은 잘 작동합니다. 그러나 일부 이미지의 경우 결과에는 다음과 같습니다 극도로 품질이 좋지. 그것은 매우 작은 (썸네일 크기)로 크기를 조정하고 다시 확대 된 것 같습니다. 그러나 이미지의 해상도가 정확합니다. 어떡해?

기존 기본 이미지 :Alt Text http://img523.imageshack.us/img523/1430/naturaerowoods.jpg

예제 크기 조정 이미지 :alt text

참고 : WPF 애플리케이션이 있지만 더 쉽고 이미 트레이 아이콘에 대한 System.Windows.forms에 대한 참조가 필요하기 때문에 크기 조정에 WinForms 기능을 사용합니다.

도움이 되었습니까?

해결책

방법의 마지막 두 줄을 이것으로 변경하십시오.

var newImg = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(newImg);
g.DrawImage(origImg, new Rectangle(0,0,newWidth,newHeight));
newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
g.Dispose();

다른 팁

현재 .NET 소스를 들여다 볼 수는 없지만 문제는 Image.GetThumbnailImage 방법. MSDN조차도 "요청 된 썸네일 이미지의 크기가 약 120 x 120 픽셀의 크기를 가질 때 잘 작동하지만, 썸네일이 포함 된 이미지에서 큰 썸네일 이미지 (예 : 300 x 300)를 요청할 수 있습니다. 썸네일 이미지에서 눈에 띄는 품질 손실이 되십시오 ". 진정한 크기 조정 (즉, 썸네일이 아님)을 위해서는 다음을 사용해야합니다. Graphics.DrawImage 방법. 당신은 또한 놀아야 할 수도 있습니다 Graphics.InterpolationMode 필요한 경우 더 나은 품질을 얻으려면.

썸네일을 만들지 않으면 GetThumbnailImage 아마 좋은 생각이 아닙니다 ...

다른 옵션의 경우 살펴보십시오 이 CodeProject 기사. 특히 새로운 이미지를 만들고 Graphics 그것을 위해 보간 모드를 설정합니다 HighQualityBicubic 그래픽에 원본 이미지를 그립니다. 적어도 시도해 볼 가치가 있습니다.

표시된대로 MSDN, GetThumbnailImage() 임의의 이미지 스케일링을 수행하도록 설계되지 않았습니다. 120x120을 초과하는 것은 수동으로 조정해야합니다. 대신 시도해보십시오.

using(var newImg = new Bitmap(origImg, newWidth, newHeight))
{
    newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
}

편집하다

설명의 지점으로,이 과부하는 Bitmap 생성자 호출 Graphics.DrawImage, 보간을 통제 할 수는 없지만.

이 코드 대신 :

newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);

이것을 사용하십시오 :

System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.EncoderParameters param = new System.Drawing.Imaging.EncoderParameters(1);
param.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
newImg.Save(dest_img, info[1], param);

예를 들어, 원본 이미지는 JPG이고 크기가 크기가 큰 이미지는 PNG입니다. 의도적 인 형식간에 변환하고 있습니까? 다른 LOSSEY 압축 체계 사이를 전환하면 품질 손실이 발생할 수 있습니다.

이미지 크기를 조정할 때 이미지의 크기를 증가 시키거나 줄이고 있습니까? 작은 이미지에서 더 큰 이미지를 만들고 있다면 이런 종류의 저하가 예상됩니다.

이미지를 확대하면 이미지가 분해됩니다.

일부 카메라는 아마도 장치 자체의 미리보기 목적으로 파일 자체에 크기가 큰 썸네일을 넣습니다.

getThumbnail 메소드는 실제로이 썸네일 이미지를 가져옵니다.

쉬운 솔루션은 크기 조정 또는 기타 작업을 수행하기 전에 .NET을 속이는 것입니다. 그렇게 ....

img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX); 
//removes thumbnails from digital camera shots
img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);

제약 제한 비율을 조정하려는 경우 System.Drawing.image에 확장 메소드를 작성하여 편리하게 찾을 수 있습니다.

/// <summary>
/// 
/// </summary>
/// <param name="img"></param>
/// <param name="size">Size of the constraining proportion</param>
/// <param name="constrainOnWidth"></param>
/// <returns></returns>
public static System.Drawing.Image ResizeConstrainProportions(this System.Drawing.Image img,
    int size, bool constrainOnWidth, bool dontResizeIfSmaller)
{
    if (dontResizeIfSmaller && (img.Width < size))
        return img;
    img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX); 
    img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);
    float ratio = 0;
    ratio = (float)img.Width / (float)img.Height;

    int height, width = 0;
    if (constrainOnWidth)
    {
        height = (int)(size / ratio);
        width = size;
    }
    else
    {
        width = (int)(size * ratio);
        height = size;
    }
    return img.GetThumbnailImage(width, height, null, (new System.IntPtr(0)));
}

이것은 다음 요소에 따라 크게 다를 것입니다.

  1. 대상 해상도가 원래 해상도의 "자연"척도와 얼마나 밀접한 일과 일치 하는가
  2. 소스 이미지 색상 깊이
  3. 이미지 유형 - 일부는 다른 것보다 더 손실입니다.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top