고품질 이미지 스케일링 라이브러리
Photoshop만큼 품질 수준이 높은 C #으로 이미지의 크기를 조정하고 싶습니다. 이 작업을 수행하는 데 사용할 수있는 C # 이미지 처리 라이브러리가 있습니까?
다음은 살펴보고 사용할 수있는 잘 설명 된 이미지 조작 도우미 클래스입니다. C #에서 특정 이미지 조작 작업을 수행하는 방법에 대한 예제로 작성했습니다. System.Drawing.Image, 너비 및 높이를 인수로 사용하는 ResizeImage 함수에 관심이 있습니다 .
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);
}
노트
이미지는 일회용이므로, 크기 조정 결과를 사용 선언에 할당해야합니다. 또는 마지막으로 try를 사용하여 마지막에 dispose를 호출 할 수 있습니다.
When you draw the image using GDI+ it scales quite well in my opinion. You can use this to create a scaled image.
If you want to scale your image with GDI+ you can do something like this:
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));
}
Tested libraries like Imagemagick and GD are available for .NET
You could also read up on things like bicubic interpolation and write your own.
CodeProject articles discussing and sharing source code for scaling images:
- Two Pass Scaling using Filters
- Matrix Transformation of Images in C#, using .NET GDI+
- Resizing a Photographic image with GDI+ for .NET
- Fast Dyadic Image Scaling with Haar Transform
Use this library: http://imageresizing.net
Have a read of this article by the library author: 20 Image Sizing Pitfalls with .NET
Try the different values for Graphics.InterpolationMode. There are several typical scaling algorithms available in GDI+. If one of these is sufficient for your need, you can go this route instead of relying on an external library.
You can try dotImage, one of my company's products, which includes an object for resampling images that has 18 filter types for various levels of quality.
Typical usage is:
// BiCubic is one technique available in PhotoShop
ResampleCommand resampler = new ResampleCommand(newSize, ResampleMethod.BiCubic);
AtalaImage newImage = resampler.Apply(oldImage).Image;
in addition, dotImage includes 140 some odd image processing commands including many filters similar to those in PhotoShop, if that's what you're looking for.
This might help
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;
}
Note the InterpolationMode.HighQualityBicubic
-> this is generally a good tradeoff between performance and results.
Try This basic code snippet:
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;
}
There's an article on Code Project about using GDI+ for .NET to do photo resizing using, say, Bicubic interpolation.
There was also another article about this topic on another blog (MS employee, I think), but I can't find the link anywhere. :( Perhaps someone else can find it?
you could try this one if it's a lowres cgi 2D Image Filter
This is an article I spotted being referenced in Paint.NET's code for image resampling: Various Simple Image Processing Techniques by Paul Bourke.
You could try the magic kernel. It produces less pixelation artifacts than bicubic resample when upscaling and it also gives very good results when downscaling. The source code is available in c# from the web site.
I have some improve for Doctor Jones's answer.
It works for who wanted to how to proportional resize the image. It tested and worked for me.
The methods of class I added:
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);
}
and new available using according to this codes:
using (var resized = ImageUtilities.ResizeImage(image, ImageUtilities.GetProportionedSize(image, 50, 100)))
{
ImageUtilities.SaveJpeg(@"C:\myimage.jpeg", resized, 90);
}
참고URL : https://stackoverflow.com/questions/249587/high-quality-image-scaling-library
'programing tip' 카테고리의 다른 글
Mongo DB에서 저장과 삽입의 차이점은 무엇입니까? (0) | 2020.06.19 |
---|---|
포인터 설명을 가리키는 포인터 (0) | 2020.06.19 |
배치 파일을 기다리지 않고 응용 프로그램을 시작하는 방법은 무엇입니까? (0) | 2020.06.19 |
무엇을 ' (0) | 2020.06.18 |
페이지에서 총 시계 수를 계산하는 방법은 무엇입니까? (0) | 2020.06.18 |