مكتبة قياس الصور عالية الجودة [مغلقة]
-
05-07-2019 - |
سؤال
أرغب في تغيير حجم صورة في C# بمستوى جودة جيد مثل Photoshop.هل هناك أي مكتبة معالجة صور 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);
}
ملحوظة
تذكر أن الصور يمكن التخلص منها، لذلك تحتاج إلى تعيين نتيجة تغيير الحجم لإعلان الاستخدام (أو يمكنك استخدام المحاولة أخيرًا والتأكد من استدعاء التخلص في النهاية).
نصائح أخرى
عند رسم الصورة باستخدام 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));
}
والمكتبات اختبار مثل يماغيماغيك و <لأ href = "HTTP: //gd-sharp.sourceforge. صافي / "يختلط =" نوفولو noreferrer "> GD هي متاحة ل. NET
هل يمكن قراءة أيضا على أشياء مثل الاستيفاء bicubic واكتب ما تريد.
مقالات CodeProject تناقش وتشارك الكود المصدري لـ تحجيم الصور:
استخدم هذه المكتبة: http://imageresizing.net
هل لديك قراءة هذا المقال من قبل المؤلف مكتبة: 20 صورة تحجيم مطبات مع. NET
وحاول قيم مختلفة لGraphics.InterpolationMode. هناك العديد من الخوارزميات التحجيم النموذجية المتاحة في GDI +. إذا كان أحد هذه يكفي لحاجتك، يمكنك السير في هذا الطريق بدلا من الاعتماد على مكتبة خارجية.
ويمكنك محاولة dotImage ، واحدة من منتجات الشركة التي أعمل بها، والذي يتضمن <ل أ href = "http://www.atalasoft.com/products/dotimage/docs/Atalasoft.dotImage~Atalasoft.Imaging.ImageProcessing.ResampleCommand_members.html" يختلط = "نوفولو noreferrer"> وجوه لاختزال الصور التي لديها 18 أنواع تصفية لل مستويات مختلفة من الجودة.
والاستخدام النموذجي هو:
// BiCubic is one technique available in PhotoShop
ResampleCommand resampler = new ResampleCommand(newSize, ResampleMethod.BiCubic);
AtalaImage newImage = resampler.Apply(oldImage).Image;
وبالإضافة إلى ذلك، يتضمن dotImage 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;
}
وهناك مثل المادة على مشروع قانون حول استخدام GDI + ل. NET للقيام الصورة تغيير حجم استخدام، مثلا، Bicubic الاستيفاء.
وكان هناك أيضا مقال آخر حول هذا الموضوع على آخر بلوق (موظف MS، على ما أظن)، ولكن لا أستطيع العثور على وصلة في أي مكان. :( ربما شخص آخر يمكن العثور عليه؟
هل يمكن أن تحاول هذه واحدة اذا كان لCGI lowres 2D صورة المرشح
وهذا هو المادة الأولى رصدت تتم الإشارة في التعليمات البرمجية Paint.NET لاختزال صورة: مختلف تقنيات بسيطة معالجة الصور بول بورك.
هل يمكن أن تحاول نواة السحر . وتنتج أقل تشويهات البكسل من إعادة تشكيل bicubic عندما رفع مستوى وكما انه يعطي نتائج جيدة جدا عند تصغير. متاح في ج # من موقع شفرة المصدر.
ولدي بعض تحسين للإجابة الدكتور جونز.
وكان يعمل لمن يريد كيفية تغيير حجم يتناسب الصورة. اختبرت وعملت بالنسبة لي.
وطرق الدرجة أضفت:
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);
}