การปรับขนาดรูปภาพโดยไม่สูญเสียคุณภาพใด ๆ [ปิด]


109

ฉันจะปรับขนาดภาพได้อย่างไรโดยที่คุณภาพของภาพไม่ได้รับผลกระทบ


คุณสามารถให้รายละเอียดเพิ่มเติมได้หรือไม่? รูปภาพของคุณมีขนาดใหญ่เพียงใดและคุณต้องการให้มีขนาดเท่าใด
Mark Ransom


6
imageresizing.net - ห้องสมุดนี้สร้างภาพคุณภาพสูงสุดที่คุณจะได้รับจาก. NET
Lilith River

คำตอบ:


218

ดังที่rcarกล่าวว่าคุณไม่สามารถทำได้โดยไม่สูญเสียคุณภาพบางอย่างสิ่งที่ดีที่สุดที่คุณทำได้ใน c # คือ

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

2
ฉันอาจเพิ่มว่า (ถ้าเป็นไปได้) ผู้ใช้ควรเริ่มต้นด้วยภาพบิตแมปที่มีขนาดใหญ่เป็นสองเท่าจากนั้นจึงลดขนาดลง ภาพที่ได้ควรจะเนียนสวย
Pretzel

2
gr.SmoothingMode = SmoothingMode.HighQuality เป็นรหัสที่ดีกว่า ปัจจุบัน HighQuality และ AntiAlias ​​เป็นสิ่งเดียวกัน แต่บางทีในอนาคต Microsoft จะคิดค้นสิ่งใหม่ ๆ HighQuality ควรเป็นนามแฝงที่ดีที่สุดเสมอ
Eyal

4
Method 'System.Drawing.Image.Save (string filename, ImageFormat format)' จะบันทึก JPG ด้วยคุณภาพ 75 ภาพไม่ชัดและไคลเอนต์ไม่ยอมรับ สิ่งที่แก้ไขปัญหาคุณภาพคือการใช้ Save (string filename, ImageCodecInfo encoder, EncoderParameters encoderParams) แทนและระบุค่าคุณภาพที่ใกล้เคียงกับ 100 มากขึ้น
ริกา

3
สิ่งนี้ทิ้งสิ่งประดิษฐ์ไว้ที่ขอบของภาพในบางครั้ง ...
jjxtra

1
ฉันมีสิ่งประดิษฐ์ที่ชายแดนเมื่อใช้สิ่งนี้ suggesstions ใด ๆ ?
Gopichandar

32

หากคุณไม่ได้ใช้กราฟิกแบบเวกเตอร์จะไม่มีวิธีใดที่จะปรับขนาดรูปภาพได้โดยที่คุณภาพของภาพจะลดลง


1
เว้นแต่คุณจะขยายมันออกไป ...
Blair Conrad

คุณสามารถขยายได้โดยไม่สูญเสียข้อมูลใด ๆ แต่มีตัวกรองประเภทต่างๆที่คุณสามารถใช้ได้ซึ่งให้ผลลัพธ์ที่แตกต่างกันเช่นการระงับการสั่งซื้อเป็นศูนย์ต่ำผ่าน ฯลฯ
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;
}

จากที่นี่


วิธีนี้ได้ผล แต่ให้คุณภาพที่เหมือนกันกับคำตอบของ Kris Erickso ยินดีที่ได้เห็นขนาดที่ใช้แม้ว่า ...
Sam Jones


3

คุณไม่สามารถทำได้ด้วยกราฟิกแรสเตอร์

สิ่งที่คุณสามารถทำได้ด้วยการกรองและการปรับให้เรียบคือการปรับขนาดโดยไม่สูญเสียคุณภาพที่สังเกตเห็นได้

นอกจากนี้คุณยังสามารถเปลี่ยนข้อมูลเมตา DPI ของรูปภาพ (สมมติว่ามีบางส่วน) ซึ่งจะคงจำนวนพิกเซลเท่าเดิม แต่จะเปลี่ยนวิธีคิดของโปรแกรมแก้ไขภาพในการวัด 'โลกแห่งความจริง'

และเพื่อให้ครอบคลุมฐานทั้งหมดหากคุณหมายถึงขนาดไฟล์ของรูปภาพจริง ๆ ไม่ใช่ขนาดของรูปภาพจริงฉันขอแนะนำให้คุณดูการเข้ารหัสข้อมูลรูปภาพแบบไม่สูญเสีย คำแนะนำของฉันสำหรับสิ่งนี้คือการบันทึกรูปภาพใหม่เป็นไฟล์. png (ฉันมักจะใช้ paint เป็นตัวแปลงรหัสฟรีสำหรับรูปภาพใน windows โหลดรูปภาพเป็นสีบันทึกเป็นรูปแบบใหม่)


3

คุณไม่สามารถปรับขนาดรูปภาพได้โดยไม่สูญเสียคุณภาพบางส่วนเพียงเพราะคุณกำลังลดจำนวนพิกเซล

อย่าลดขนาดฝั่งไคลเอ็นต์เนื่องจากเบราว์เซอร์ไม่สามารถปรับขนาดรูปภาพได้ดี

สิ่งที่คุณทำได้คือเปลี่ยนขนาดตามโปรแกรมก่อนที่จะแสดงผลหรือเมื่อผู้ใช้อัปโหลด

นี่คือบทความที่อธิบายวิธีหนึ่งในการดำเนินการนี้ใน c #: http://www.codeproject.com/KB/GDI-plus/imageresize.aspx


"เบราว์เซอร์ทำงานได้ไม่ดีในการปรับขนาดภาพ" ซึ่งอาจเป็นจริงในปี '08 แต่โชคดีที่เราอยู่ห่างออกไปหลายไมล์ในพื้นที่นี้ (ในระดับที่ดีเนื่องจาก IE เวอร์ชันเก่าค่อยๆจางหายไป)
Camilo Martin

2

ดูว่าคุณชอบคุณภาพการปรับขนาดภาพของโมดูล ASP.NET โอเพนซอร์สหรือไม่ มีการสาธิตสดดังนั้นคุณสามารถจัดการกับมันได้ด้วยตัวเอง ให้ผลลัพธ์ที่ (สำหรับฉัน) ไม่สามารถแยกความแตกต่างจากเอาต์พุต Photoshop นอกจากนี้ยังมีขนาดไฟล์ที่ใกล้เคียงกัน - MS ทำงานได้ดีกับตัวเข้ารหัส JPEG


JPEG เป็นรูปแบบที่ค่อนข้างตรงไปตรงมา ไม่มีอะไรมากที่คุณสามารถทำได้เพื่อเอาชนะการใช้งานอ้างอิงในแง่ของคุณภาพ / ขนาดไฟล์เพราะในตอนท้ายมันเป็นเพียงค่าสัมประสิทธิ์ DCT ที่มีการบีบอัดทั่วไป
Camilo Martin

1

มีบางอย่างอยู่ที่นั่นการปรับขนาดตามบริบทไม่รู้ว่าคุณจะสามารถใช้งานได้หรือไม่ แต่ก็คุ้มค่าที่จะดูนั่นแน่นอน

การสาธิตวิดีโอที่ดี (การขยายปรากฏขึ้นตรงกลาง) http://www.youtube.com/watch?v=vIFCV2spKtg

ที่นี่อาจมีรหัสบางอย่าง http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/

นั่นคือ overkill? อาจมีฟิลเตอร์ง่ายๆที่คุณสามารถใช้กับภาพขยายเพื่อเบลอพิกเซลเล็กน้อยคุณสามารถดูได้


ฉันสงสัยว่ามันไม่เกี่ยวข้องกับคำถามเดิม แต่ฉันชอบเทคนิคนี้
Matt Cruikshank

1

คุณปรับขนาดให้ใหญ่ขึ้นหรือเล็กลง? โดย% เล็กน้อยหรือโดยตัวประกอบที่ใหญ่กว่าเช่น 2x, 3x? คุณภาพสำหรับใบสมัครของคุณหมายถึงอะไร? และภาพประเภทใด - ภาพถ่ายภาพวาดลายเส้นขอบแข็งหรืออะไร? การเขียนโค้ดการเจียรพิกเซลระดับต่ำของคุณเองหรือพยายามทำด้วยไลบรารีที่มีอยู่ (.net หรืออะไรก็ตาม) ให้มากที่สุด?

มีองค์ความรู้ขนาดใหญ่ในหัวข้อนี้ แนวคิดหลักคือการสอดแทรก

คำแนะนำในการท่องเว็บ:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
* สำหรับ 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 * นี่คือ java เฉพาะ แต่อาจมีการศึกษา - http: //today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html


1

คุณสามารถเพิ่มรหัสลายน้ำในชั้นนี้ได้ที่นี่:

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

    }

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.