Mengubah ukuran Gambar tanpa kehilangan kualitas apa pun [tertutup]

108

Bagaimana cara mengubah ukuran gambar, dengan kualitas gambar tidak terpengaruh?

publik statis
sumber
Bisakah Anda memberi kami detail lebih lanjut? Seberapa besar gambar Anda, dan berapa ukuran yang Anda butuhkan?
Mark Ransom
6
imageresizing.net - Perpustakaan ini menghasilkan gambar dengan kualitas terbaik yang bisa Anda dapatkan dengan .NET
Lilith River

Jawaban:

217

Seperti yang dikatakan rcar , Anda tidak bisa tanpa kehilangan beberapa kualitas, hal terbaik yang dapat Anda lakukan di c # adalah:

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));
}
Kris Erickson
sumber
2
Saya dapat menambahkan bahwa (jika mungkin) pengguna harus mulai dengan gambar Bitmap yang, katakanlah, dua kali lebih besar dari yang dibutuhkan dan kemudian menurunkannya. Gambar yang dihasilkan harus cukup halus.
Pretzel
2
gr.SmoothingMode = SmoothingMode.HighQuality adalah kode yang lebih baik. Saat ini HighQuality dan AntiAlias ​​adalah hal yang sama, tetapi mungkin di masa depan Microsoft akan menciptakan sesuatu yang baru. HighQuality harus selalu menjadi alias untuk yang terbaik.
Eyal
4
Metode 'System.Drawing.Image.Save (string filename, ImageFormat format)' menyimpan JPG dengan kualitas 75. Gambar itu kabur dan tidak dapat diterima oleh klien. Yang memperbaiki masalah kualitas adalah menggunakan Simpan (nama file string, encoder ImageCodecInfo, EncoderParameters encoderParams) sebagai gantinya, dan menentukan nilai kualitas yang mendekati 100.
Riga
3
Ini terkadang meninggalkan artefak di perbatasan gambar ...
jjxtra
1
Saya memiliki artefak di perbatasan untuk menggunakan ini. Ada saran?
Gopichandar
32

Kecuali Anda melakukan grafik vektor, tidak ada cara untuk mengubah ukuran gambar tanpa berpotensi kehilangan beberapa kualitas gambar.

Randy
sumber
1
kecuali jika Anda mengembangkannya ...
Blair Conrad
Anda dapat mengembangkannya tanpa kehilangan informasi apa pun, tetapi ada berbagai jenis filter yang dapat Anda gunakan yang memberikan hasil berbeda - penangguhan tanpa perintah, akses rendah, dll.
Adam Rosenfield
24
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;
}

dari sini

ozba
sumber
Ini berfungsi, tetapi mengembalikan kualitas yang identik dengan jawaban Kris Erickso. Senang melihat Ukuran digunakan meskipun ...
Sam Jones
3

Kecuali Anda mengubah ukurannya, Anda tidak dapat melakukan ini dengan grafik raster.

Yang dapat Anda lakukan dengan pemfilteran dan penghalusan yang baik adalah mengubah ukuran tanpa kehilangan kualitas yang terlihat .

Anda juga dapat mengubah metadata DPI gambar (dengan asumsi ada beberapa) yang akan mempertahankan jumlah piksel yang persis sama, tetapi akan mengubah cara editor gambar memikirkannya dalam pengukuran 'dunia nyata'.

Dan hanya untuk mencakup semua basis, jika yang Anda maksud hanyalah ukuran file gambar dan bukan dimensi gambar yang sebenarnya, saya sarankan Anda melihat pengkodean lossless dari data gambar. Saran saya untuk ini adalah menyimpan kembali gambar sebagai file .png (Saya cenderung menggunakan paint sebagai transcoder gratis untuk gambar di windows. Muat gambar di paint, simpan seperti dalam format baru)

workmad3
sumber
3

Anda tidak dapat mengubah ukuran gambar tanpa kehilangan beberapa kualitas, hanya karena Anda mengurangi jumlah piksel.

Jangan mengurangi ukuran sisi klien, karena browser tidak melakukan pekerjaan yang baik dalam mengubah ukuran gambar.

Yang dapat Anda lakukan adalah mengubah ukuran secara terprogram sebelum Anda merendernya, atau saat pengguna mengunggahnya.

Berikut adalah artikel yang menjelaskan salah satu cara melakukan ini di c #: http://www.codeproject.com/KB/GDI-plus/imageresize.aspx

AaronS
sumber
"Browser tidak melakukan pekerjaan yang baik untuk mengubah ukuran gambar" - ini mungkin benar di tahun '08, tetapi untungnya kami berada jauh di depan dalam bidang ini sekarang (sebagian besar karena versi IE lama perlahan memudar).
Camilo Martin
2

Lihat apakah Anda menyukai kualitas pengubahan ukuran gambar dari modul ASP.NET open source ini. Ada demo langsung, jadi Anda bisa mengotak-atiknya sendiri. Ini menghasilkan hasil yang (bagi saya) tidak mungkin dibedakan dari keluaran Photoshop. Ini juga memiliki ukuran file yang serupa - MS melakukan pekerjaan dengan baik pada encoder JPEG mereka.


sumber
Nah, JPEG adalah format yang relatif mudah. Tidak banyak yang dapat Anda lakukan untuk mengalahkan implementasi referensi dalam hal kualitas / ukuran file karena pada akhirnya itu hanya koefisien DCT dengan kompresi generik.
Camilo Martin
1

Ada sesuatu di luar sana, pengubahan ukuran sadar konteks, tidak tahu apakah Anda akan dapat menggunakannya, tetapi itu layak untuk dilihat, itu pasti

Video demo yang bagus (Pembesaran muncul di tengah) http://www.youtube.com/watch?v=vIFCV2spKtg

Di sini mungkin ada beberapa kode. http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/

Apakah itu berlebihan? Mungkin ada beberapa filter mudah yang bisa Anda terapkan pada gambar yang diperbesar untuk sedikit mengaburkan piksel, Anda bisa melihatnya.

Pemenang
sumber
Saya menduga ini tidak ada hubungannya dengan pertanyaan awal, tetapi saya sangat menyukai teknik ini.
Matt Cruikshank
1

Apakah Anda mengubah ukuran lebih besar atau lebih kecil? Dengan% kecil atau dengan faktor yang lebih besar seperti 2x, 3x? Apa yang Anda maksud dengan kualitas untuk aplikasi Anda? Dan jenis gambar apa - foto, gambar garis tajam, atau apa? Menulis kode penggilingan piksel tingkat rendah Anda sendiri atau mencoba melakukannya sebanyak mungkin dengan pustaka yang ada (.net atau apa pun)?

Ada banyak pengetahuan tentang topik ini. Konsep utamanya adalah interpolasi.

Rekomendasi penjelajahan:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* untuk 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 * ini khusus untuk Java tetapi mungkin mendidik - http: //today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html

DarenW
sumber
1

Di sini Anda dapat menemukan juga menambahkan kode watermark di kelas ini:

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>();
        }

    }
cagin
sumber
0

Berikut adalah utas forum yang menyediakan contoh kode pengubah ukuran gambar C #. Anda dapat menggunakan salah satu pengikat pustaka GD untuk melakukan pengambilan sampel ulang di C #.

jimg
sumber