Làm cách nào để thay đổi kích thước hình ảnh mà chất lượng hình ảnh không bị ảnh hưởng?
Làm cách nào để thay đổi kích thước hình ảnh mà chất lượng hình ảnh không bị ảnh hưởng?
Câu trả lời:
Như rcar đã nói, bạn không thể không giảm chất lượng, điều tốt nhất bạn có thể làm trong c # là:
Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));
}
Trừ khi bạn đang làm đồ họa vector, không có cách nào để thay đổi kích thước hình ảnh mà không có khả năng làm giảm chất lượng hình ảnh.
private static Image resizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return (Image)b;
}
Tôi tin rằng những gì bạn muốn làm là "Thay đổi kích thước / Lấy mẫu lại" hình ảnh của bạn. Đây là một trang web tốt cung cấp hướng dẫn và cung cấp một lớp tiện ích (Tôi cũng tình cờ sử dụng):
http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx
Trừ khi bạn thay đổi kích thước, bạn không thể làm điều này với đồ họa raster.
Những gì bạn có thể làm với tính năng lọc và làm mịn tốt là thay đổi kích thước mà không làm giảm chất lượng đáng chú ý .
Bạn cũng có thể thay đổi siêu dữ liệu DPI của hình ảnh (giả sử nó có một số) sẽ giữ chính xác cùng một số lượng pixel, nhưng sẽ thay đổi cách người chỉnh sửa hình ảnh nghĩ về nó trong các phép đo 'thế giới thực'.
Và chỉ để bao gồm tất cả các cơ sở, nếu bạn thực sự muốn chỉ kích thước tệp của hình ảnh chứ không phải kích thước hình ảnh thực tế, tôi khuyên bạn nên xem xét mã hóa không mất dữ liệu của dữ liệu hình ảnh. Đề xuất của tôi cho việc này là lưu lại hình ảnh dưới dạng tệp .png (Tôi có xu hướng sử dụng paint làm trình chuyển mã miễn phí cho hình ảnh trong windows. Tải hình ảnh trong paint, lưu ở định dạng mới)
Bạn không thể thay đổi kích thước hình ảnh mà không làm giảm chất lượng, đơn giản vì bạn đang giảm số lượng pixel.
Không giảm kích thước phía máy khách, bởi vì các trình duyệt không thực hiện tốt công việc thay đổi kích thước hình ảnh.
Những gì bạn có thể làm là thay đổi kích thước theo chương trình trước khi hiển thị hoặc khi người dùng tải lên.
Đây là một bài viết giải thích một cách để thực hiện việc này trong c #: http://www.codeproject.com/KB/GDI-plus/imageresize.aspx
Xem bạn có thích chất lượng thay đổi kích thước hình ảnh của mô-đun ASP.NET mã nguồn mở này không. Có một bản trình diễn trực tiếp, vì vậy bạn có thể tự làm với nó. Nó mang lại kết quả mà (đối với tôi) không thể phân biệt được với đầu ra của Photoshop. Nó cũng có kích thước tệp tương tự - MS đã làm rất tốt trên bộ mã hóa JPEG của họ.
Có một cái gì đó ngoài kia, thay đổi kích thước theo ngữ cảnh, không biết bạn có sử dụng được không, nhưng nó rất đáng xem, đó là điều chắc chắn
Bản giới thiệu video đẹp (Phóng to xuất hiện ở giữa) http://www.youtube.com/watch?v=vIFCV2spKtg
Ở đây có thể có một số mã. http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/
Đó có phải là quá mức cần thiết? Có thể có một số bộ lọc dễ dàng bạn có thể áp dụng cho hình ảnh phóng to để làm mờ các pixel một chút, bạn có thể xem xét điều đó.
Bạn đang thay đổi kích thước lớn hơn hay nhỏ hơn? Bằng một% nhỏ hay một hệ số lớn hơn như 2x, 3x? Ý bạn là gì về chất lượng cho ứng dụng của bạn? Và loại hình ảnh nào - ảnh chụp, hình vẽ đường nét cứng, hay gì? Viết mã mài pixel cấp thấp của riêng bạn hoặc cố gắng làm điều đó càng nhiều càng tốt với các thư viện hiện có (.net hoặc bất cứ điều gì)?
Có một lượng lớn kiến thức về chủ đề này. Khái niệm chính là nội suy.
Đề xuất duyệt web:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* cho C #: https: //secure.codeproject.com/KB/GDI-plus/imageprocessing4.aspx?display=PrintAll&fid=3657&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=26&select=629945
* đây là java cụ thể nhưng có thể mang tính giáo dục - http: //today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
Tại đây, bạn cũng có thể tìm thêm mã hình mờ trong lớp này:
public class ImageProcessor
{
public Bitmap Resize(Bitmap image, int newWidth, int newHeight, string message)
{
try
{
Bitmap newImage = new Bitmap(newWidth, Calculations(image.Width, image.Height, newWidth));
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(image, new Rectangle(0, 0, newImage.Width, newImage.Height));
var myBrush = new SolidBrush(Color.FromArgb(70, 205, 205, 205));
double diagonal = Math.Sqrt(newImage.Width * newImage.Width + newImage.Height * newImage.Height);
Rectangle containerBox = new Rectangle();
containerBox.X = (int)(diagonal / 10);
float messageLength = (float)(diagonal / message.Length * 1);
containerBox.Y = -(int)(messageLength / 1.6);
Font stringFont = new Font("verdana", messageLength);
StringFormat sf = new StringFormat();
float slope = (float)(Math.Atan2(newImage.Height, newImage.Width) * 180 / Math.PI);
gr.RotateTransform(slope);
gr.DrawString(message, stringFont, myBrush, containerBox, sf);
return newImage;
}
}
catch (Exception exc)
{
throw exc;
}
}
public int Calculations(decimal w1, decimal h1, int newWidth)
{
decimal height = 0;
decimal ratio = 0;
if (newWidth < w1)
{
ratio = w1 / newWidth;
height = h1 / ratio;
return height.To<int>();
}
if (w1 < newWidth)
{
ratio = newWidth / w1;
height = h1 * ratio;
return height.To<int>();
}
return height.To<int>();
}
}
Đây là một chuỗi diễn đàn cung cấp mẫu mã thay đổi kích thước hình ảnh C #. Bạn có thể sử dụng một trong các chất kết dính thư viện GD để lấy mẫu lại trong C #.