문제

Photoshop만큼 좋은 수준으로 C#에서 이미지를 확장하고 싶습니다. 이 작업을 수행 할 수있는 C# 이미지 처리 라이브러리가 있습니까?

도움이 되었습니까?

해결책

다음은보고 사용할 수있는 멋진 이미지 조작 도우미 클래스입니다. C#에서 특정 이미지 조작 작업을 수행하는 방법의 예로 작성했습니다. 당신은 당신이 관심을 가질 것입니다 크기 조정 System.drawing.image, 너비 및 높이를 인수로 취하는 함수.

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

namespace DoctaJonez.Drawing.Imaging
{
    /// <summary>
    /// Provides various image untilities, such as high quality resizing and the ability to save a JPEG.
    /// </summary>
    public static class ImageUtilities
    {    
        /// <summary>
        /// A quick lookup for getting image encoders
        /// </summary>
        private static Dictionary<string, ImageCodecInfo> encoders = null;

        /// <summary>
        /// A lock to prevent concurrency issues loading the encoders.
        /// </summary>
        private static object encodersLock = new object();

        /// <summary>
        /// A quick lookup for getting image encoders
        /// </summary>
        public static Dictionary<string, ImageCodecInfo> Encoders
        {
            //get accessor that creates the dictionary on demand
            get
            {
                //if the quick lookup isn't initialised, initialise it
                if (encoders == null)
                {
                    //protect against concurrency issues
                    lock (encodersLock)
                    {
                        //check again, we might not have been the first person to acquire the lock (see the double checked lock pattern)
                        if (encoders == null)
                        {
                            encoders = new Dictionary<string, ImageCodecInfo>();

                            //get all the codecs
                            foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
                            {
                                //add each codec to the quick lookup
                                encoders.Add(codec.MimeType.ToLower(), codec);
                            }
                        }
                    }
                }

                //return the lookup
                return encoders;
            }
        }

        /// <summary>
        /// Resize the image to the specified width and height.
        /// </summary>
        /// <param name="image">The image to resize.</param>
        /// <param name="width">The width to resize to.</param>
        /// <param name="height">The height to resize to.</param>
        /// <returns>The resized image.</returns>
        public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
        {
            //a holder for the result
            Bitmap result = new Bitmap(width, height);
            //set the resolutions the same to avoid cropping due to resolution differences
            result.SetResolution(image.HorizontalResolution, image.VerticalResolution);

            //use a graphics object to draw the resized image into the bitmap
            using (Graphics graphics = Graphics.FromImage(result))
            {
                //set the resize quality modes to high quality
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //draw the image into the target bitmap
                graphics.DrawImage(image, 0, 0, result.Width, result.Height);
            }

            //return the resulting bitmap
            return result;
        }

        /// <summary> 
        /// Saves an image as a jpeg image, with the given quality 
        /// </summary> 
        /// <param name="path">Path to which the image would be saved.</param> 
        /// <param name="quality">An integer from 0 to 100, with 100 being the 
        /// highest quality</param> 
        /// <exception cref="ArgumentOutOfRangeException">
        /// An invalid value was entered for image quality.
        /// </exception>
        public static void SaveJpeg(string path, Image image, int quality)
        {
            //ensure the quality is within the correct range
            if ((quality < 0) || (quality > 100))
            {
                //create the error message
                string error = string.Format("Jpeg image quality must be between 0 and 100, with 100 being the highest quality.  A value of {0} was specified.", quality);
                //throw a helpful exception
                throw new ArgumentOutOfRangeException(error);
            }

            //create an encoder parameter for the image quality
            EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            //get the jpeg codec
            ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");

            //create a collection of all parameters that we will pass to the encoder
            EncoderParameters encoderParams = new EncoderParameters(1);
            //set the quality parameter for the codec
            encoderParams.Param[0] = qualityParam;
            //save the image using the codec and the parameters
            image.Save(path, jpegCodec, encoderParams);
        }

        /// <summary> 
        /// Returns the image codec with the given mime type 
        /// </summary> 
        public static ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            //do a case insensitive search for the mime type
            string lookupKey = mimeType.ToLower();

            //the codec to return, default to null
            ImageCodecInfo foundCodec = null;

            //if we have the encoder, get it to return
            if (Encoders.ContainsKey(lookupKey))
            {
                //pull the codec from the lookup
                foundCodec = Encoders[lookupKey];
            }

            return foundCodec;
        } 
    }
}

업데이트

몇몇 사람들은 imageUtilities 클래스를 소비하는 방법에 대한 샘플에 대한 의견에 묻고 있습니다.

//resize the image to the specified height and width
using (var resized = ImageUtilities.ResizeImage(image, 50, 100))
{
    //save the resized image as a jpeg with a quality of 90
    ImageUtilities.SaveJpeg(@"C:\myimage.jpeg", resized, 90);
}

메모

이미지는 일회용이므로 크기 조정 결과를 사용한 선언에 할당해야합니다 (또는 최종적으로 시도를 사용하고 최종적으로 Dispose를 호출 할 수 있습니다).

다른 팁

gdi+를 사용하여 이미지를 그리면 제 생각에는 상당히 스케일이 있습니다. 이것을 사용하여 스케일링 된 이미지를 만들 수 있습니다.

GDI+로 이미지를 확장하려면 다음과 같은 작업을 수행 할 수 있습니다.

Bitmap original = ...
Bitmap scaled = new Bitmap(new Size(original.Width * 4, original.Height * 4));
using (Graphics graphics = Graphics.FromImage(scaled)) {
  graphics.DrawImage(original, new Rectangle(0, 0, scaled.Width, scaled.Height));
}

테스트 된 라이브러리와 같은 Imagemagick 그리고 GD .NET에 사용할 수 있습니다

Bicubic 보간과 같은 것들을 읽고 자신의 글을 쓸 수도 있습니다.

이 라이브러리 사용 : http://imageresizing.net

도서관 저자 의이 기사를 읽으십시오. .NET을 사용한 20 개의 이미지 크기의 함정

Graphics.InterpolationMode의 다른 값을 시도하십시오. GDI+에는 몇 가지 일반적인 스케일링 알고리즘이 있습니다. 이 중 하나가 필요에 충분한 경우 외부 라이브러리에 의존하는 대신이 경로를 갈 수 있습니다.

당신은 시도 할 수 있습니다 dotimage, 내 회사의 제품 중 하나, 여기에는 리샘플링을위한 객체 가지고있는 이미지 18 필터 유형 다양한 수준의 품질.

일반적인 사용은 다음과 같습니다.

// BiCubic is one technique available in PhotoShop
ResampleCommand resampler = new ResampleCommand(newSize, ResampleMethod.BiCubic);
AtalaImage newImage = resampler.Apply(oldImage).Image;

또한 DotImage에는 Photoshop의 필터와 유사한 많은 필터를 포함하여 140 개의 일부 홀수 이미지 처리 명령이 포함되어 있습니다.

이것은 도움이 될 수 있습니다

    public Image ResizeImage(Image source, RectangleF destinationBounds)
    {
        RectangleF sourceBounds = new RectangleF(0.0f,0.0f,(float)source.Width, (float)source.Height);
        RectangleF scaleBounds = new RectangleF();

        Image destinationImage = new Bitmap((int)destinationBounds.Width, (int)destinationBounds.Height);
        Graphics graph = Graphics.FromImage(destinationImage);
        graph.InterpolationMode =
            System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

        // Fill with background color
        graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), destinationBounds);

        float resizeRatio, sourceRatio;
        float scaleWidth, scaleHeight;

        sourceRatio = (float)source.Width / (float)source.Height;

        if (sourceRatio >= 1.0f)
        {
            //landscape
            resizeRatio = destinationBounds.Width / sourceBounds.Width;
            scaleWidth = destinationBounds.Width;
            scaleHeight = sourceBounds.Height * resizeRatio;
            float trimValue = destinationBounds.Height - scaleHeight;
            graph.DrawImage(source, 0, (trimValue / 2), destinationBounds.Width, scaleHeight);
        }
        else
        {
            //portrait
            resizeRatio = destinationBounds.Height/sourceBounds.Height;
            scaleWidth = sourceBounds.Width * resizeRatio;
            scaleHeight = destinationBounds.Height;
            float trimValue = destinationBounds.Width - scaleWidth;
            graph.DrawImage(source, (trimValue / 2), 0, scaleWidth, destinationBounds.Height);
        }

        return destinationImage;

    }

참고 InterpolationMode.HighQualityBicubic -> 이것은 일반적으로 성능과 결과 사이의 좋은 트레이드 오프입니다.

이 기본 코드 스 니펫을 사용해보십시오.

private static Bitmap ResizeBitmap(Bitmap srcbmp, int width, int height )
{
    Bitmap newimage = new Bitmap(width, height);
    using (Graphics g = Graphics.FromImage(newimage))
           g.DrawImage(srcbmp, 0, 0, width, height);
    return newimage;
}

있습니다 코드 프로젝트에 관한 기사 .NET 용 GDI+를 사용하여 Bicubic 보간을 사용하여 사진 크기 조정을 수행합니다.

다른 블로그 에이 주제에 대한 또 다른 기사가 있었지만 (MS Employee, 생각합니다) 어디서나 링크를 찾을 수 없습니다. :( 아마도 다른 사람이 그것을 찾을 수 있습니까?

Lowres CGI라면 이것을 시도 할 수 있습니다.2D 이미지 필터

이것은 이미지 리샘플링을위한 Paint.net의 코드에서 참조되는 기사입니다. 다양한 간단한 이미지 처리 기술 Paul Bourke.

당신은 시도 할 수 있습니다 마법 커널. 업 스케일링시 이중 큐비 리 샘플보다 픽셀 화 아티팩트를 덜 생성하고 다운 스케일링시 매우 우수한 결과를 제공합니다. 소스 코드는 웹 사이트에서 C#에서 사용할 수 있습니다.

Jones 박사의 답변에 대해 약간의 개선이 있습니다.

그것은 이미지를 비례하는 방법을 원했던 사람을 위해 작동합니다. 그것은 나를 위해 테스트하고 일했습니다.

클래스 I의 방법은 다음을 추가했습니다.

public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, Size size)
{
    return ResizeImage(image, size.Width, size.Height);
}


public static Size GetProportionedSize(Image image, int maxWidth, int maxHeight, bool withProportion)
{
    if (withProportion)
    {
        double sourceWidth = image.Width;
        double sourceHeight = image.Height;

        if (sourceWidth < maxWidth && sourceHeight < maxHeight)
        {
            maxWidth = (int)sourceWidth;
            maxHeight = (int)sourceHeight;
        }
        else
        {
            double aspect = sourceHeight / sourceWidth;

            if (sourceWidth < sourceHeight)
            {
                maxWidth = Convert.ToInt32(Math.Round((maxHeight / aspect), 0));
            }
            else
            {
                maxHeight = Convert.ToInt32(Math.Round((maxWidth * aspect), 0));
            }
        }
    }

    return new Size(maxWidth, maxHeight);
}

이 코드에 따라 사용 가능한 새로운 사용 가능 :

using (var resized = ImageUtilities.ResizeImage(image, ImageUtilities.GetProportionedSize(image, 50, 100)))
{
    ImageUtilities.SaveJpeg(@"C:\myimage.jpeg", resized, 90);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top