如何在不降低图像质量的情况下调整图像大小? [英] How do I resize an image without losing its quality?

查看:114
本文介绍了如何在不降低图像质量的情况下调整图像大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用c#调整图像大小,通过对其宽度和高度进行硬编码两个值,但我无法找到在上传时调整大小而不会降低其质量的方法。



我尝试过:



这是我的代码。



 {
OpenFileDialog opendialog;
SaveFileDialog savedialog;
Image target_image;
int width;
int height;

public Form1()
{
InitializeComponent();
opendialog = new OpenFileDialog();

opendialog.RestoreDirectory = true;
opendialog.InitialDirectory =C:\\;
opendialog.FilterIndex = 1;
opendialog.Filter =jpg文件(* .jpg)| * .jpg | gif文件(* .gif)| * .gif | png文件(* .png)| * .png | bmp文件(*。 BMP)| * .BMP;

savedialog = new SaveFileDialog();

savedialog.RestoreDirectory = true;
savedialog.InitialDirectory =C:\\;
savedialog.FilterIndex = 1;
savedialog.Filter =jpg文件(* .jpg)| * .jpg | gif文件(* .gif)| * .gif | png文件(* .png)| * .png | bmp文件(*。 BMP)| * .BMP;
}

private void btnOpen_Click(object sender,EventArgs e)
{
try
{
if(opendialog.ShowDialog()= = DialogResult.OK)
{
target_image = Image.FromFile(opendialog.FileName);
width = target_image.Width;
height = target_image.Height;
}


target_image =调整大小(宽度,高度);


}
catch(exception ex)
{
MessageBox.Show(Error Occured,+ ex.Message);
}
}

private new Bitmap Resize(int target_width,int target_height)
{
target_width = 300;
target_height = 500;

Rectangle rectangle = new Rectangle(0,0,target_width,target_height);
Bitmap destImage = new Bitmap(target_width,target_height);
destImage.SetResolution(target_image.Horizo​​ntalResolution,target_image.VerticalResolution);
using(var g = Graphics.FromImage(destImage))
{
g.CompositingMode = CompositingMode.SourceCopy;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;

using(var wrapmode = new ImageAttributes())
{
wrapmode.SetWrapMode(WrapMode.TileFlipXY);
g.DrawImage(target_image,rectangle,0,0,target_image.Width,target_image.Height,GraphicsUnit.Pixel);
}
}
返回destImage;
}

private void btnSave_Click(object sender,EventArgs e)
{
if(savedialog.ShowDialog()== DialogResult.OK)
{
target_image.Save(savedialog.FileName);
}
}
}

解决方案

问题是当你调整大小时一个图像,当你把它变大时你要么必须添加信息,要么当它变小时要扔掉它。



这真的很难,因为你不要没有要添加的信息,你无法收回你扔掉的信息。与您在电影和电视中看到的相反,在您拥有所需的细节之前,图像无法缩放:每个像素都是一个在不添加信息的情况下无法进一步缩放的单位。



因此,当您将图像重绘为特定的高度和宽度时,如果图像较大,则要么丢弃数据,要插入 * 它可能来自周围像素的内容如果配给量y0 / y1:x0 / x1不相同,则图像开始变小或扭曲整个图像。



因此每次都要加重伤害保存jpg,你自动使质量更差,因为jpg是一种有损压缩格式,每次保存时都会抛弃数据。获取高质量的BMP文件并将其另存为JPG。打开JPG并将其另存为新的JPG。重复几次,当你与原版进行比较时,你会看到明显的退化。



除非你知道,否则你无法做任何事情。正是你正在处理的图像开始。 (这就是为什么不是每个拥有Photoshop副本的人都能产生好的效果!)





* I.e。 猜测


看看图像调整大小 - 优于GDI + [ ^ ]。

I tried to resize an image using c# by hard coding two values for its width and height but I couldn't figure out a way to resize it on upload without losing its quality.

What I have tried:

This is my code.

{
    OpenFileDialog opendialog;
    SaveFileDialog savedialog;
    Image target_image;
    int width;
    int height;

    public Form1()
    {
        InitializeComponent();
        opendialog = new OpenFileDialog();

        opendialog.RestoreDirectory = true;
        opendialog.InitialDirectory = "C:\\";
        opendialog.FilterIndex = 1;
        opendialog.Filter = "jpg Files (*.jpg)|*.jpg|gif Files (*.gif)|*.gif|png Files (*.png)|*.png |bmp Files (*.bmp)|*.bmp";

        savedialog = new SaveFileDialog();

        savedialog.RestoreDirectory = true;
        savedialog.InitialDirectory = "C:\\";
        savedialog.FilterIndex = 1;
        savedialog.Filter = "jpg Files (*.jpg)|*.jpg|gif Files (*.gif)|*.gif|png Files (*.png)|*.png |bmp Files (*.bmp)|*.bmp";
    }

    private void btnOpen_Click(object sender, EventArgs e)
    {
        try
        {
            if (opendialog.ShowDialog() == DialogResult.OK)
            {
                target_image = Image.FromFile(opendialog.FileName);
                width = target_image.Width;
                height = target_image.Height;
                }


            target_image = Resize(width, height);


        }
        catch (Exception ex)
        {
            MessageBox.Show("Error Occured, " + ex.Message);
        }
    }

    private new Bitmap Resize(int target_width, int target_height)
    {
        target_width = 300;
        target_height = 500;

        Rectangle rectangle = new Rectangle(0, 0, target_width, target_height);
        Bitmap destImage = new Bitmap(target_width, target_height);
        destImage.SetResolution(target_image.HorizontalResolution, target_image.VerticalResolution);
        using (var g = Graphics.FromImage(destImage))
        {
            g.CompositingMode = CompositingMode.SourceCopy;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;

            using (var wrapmode = new ImageAttributes())
            {
                wrapmode.SetWrapMode(WrapMode.TileFlipXY);
                g.DrawImage(target_image, rectangle, 0, 0, target_image.Width, target_image.Height, GraphicsUnit.Pixel);
            }
        }
        return destImage;
    }

    private void btnSave_Click(object sender, EventArgs e)
    {
        if (savedialog.ShowDialog() == DialogResult.OK)
        {
            target_image.Save(savedialog.FileName);
        }
    }
}

解决方案

The problem is that when you resize an image, you either had to add information when you make it bigger, or throw it away when you make it smaller.

And that is really difficult, because you don't have the information to add, and you can't get back the information you throw away. Contrary to what you see in movies and TV, images can't be zoomed until you have the detail you want: each pixel is a unit which can't be zoomed any further without adding information.

So when you redraw your image to a specific height and width, you are either throwing away data if the image was bigger, interpolating* what it might be from the surrounding pixels if the image started smaller, or distorting the whole image if the ration y0/y1 : x0/x1 is not the same.

So add insult to injury, every time to save a jpg, you automatically make the quality worse, because jpg is a lossy compression format, which throws away data each time you save. Take a top quality BMP file and save it as a JPG. Open the JPG and save it as a new JPG. Repeat a few times, and you will see really noticeable degradation when you compare against the original.

There isn't anything you can really do about this, unless you know exactly what you are processing as images to start with. (That's why not everybody with a copy of Photoshop can produce good results!)


* I.e. "guessing"


Have a look at Image Resizing - outperform GDI+[^].


这篇关于如何在不降低图像质量的情况下调整图像大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆