Member 13958707 Ответов: 2

Как изменить размер изображения без потери его качества?


Я попытался изменить размер изображения с помощью 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 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);
        }
    }
}

2 Ответов

Рейтинг:
2
Рейтинг:
19

OriginalGriff

Проблема заключается в том, что при изменении размера изображения необходимо либо добавить информацию, когда оно становится больше, либо выбросить ее, когда оно становится меньше.

И это действительно трудно, потому что у вас нет информации, чтобы добавить, и вы не можете получить обратно информацию, которую вы выбрасываете. В отличие от того, что вы видите в фильмах и телевизорах, изображения нельзя увеличить, пока у вас нет нужной детали: каждый пиксель-это единица измерения, которую нельзя увеличить дальше без добавления информации.

Поэтому, когда вы перерисовываете свое изображение на определенную высоту и ширину, вы либо выбрасываете данные, если изображение было больше, либо интерполируете* что это может быть из окружающих пикселей, если изображение стало меньше, или искажение всего изображения, если соотношение y0/y1 : x0/x1 не совпадает.

Поэтому добавьте оскорбление к травме, каждый раз, когда вы сохраняете jpg, вы автоматически ухудшаете качество, потому что jpg-это формат сжатия с потерями, который выбрасывает данные каждый раз, когда вы сохраняете. Возьмите высококачественный BMP - файл и сохраните его в формате JPG. Откройте файл JPG и сохраните его как новый файл jpg. Повторите несколько раз, и вы увидите действительно заметную деградацию, когда будете сравнивать с оригиналом.

Вы ничего не можете с этим поделать, если не знаете точно, с чего вы начинаете обработку изображений. (Вот почему не каждый, у кого есть копия Photoshop, может добиться хороших результатов!)


* То есть "угадывание"


Member 13958707

Есть ли способ изменить его размер с сохранением соотношения сторон?

OriginalGriff

Да - вы либо рисуете его в растровом изображении с тем же соотношением сторон, либо рисуете его с тем же соотношением сторон в большем растровом изображении и принимаете "полосы" по бокам или сверху и снизу.

Это не слишком сложно, все, что это означает, - это разработка правильного размера нового изображения / чертежа с использованием соотношения x/y оригинала.