تغيير حجم الصورة - في بعض الأحيان سيئة للغاية الجودة ؟

StackOverflow https://stackoverflow.com/questions/803987

سؤال

أنا تغيير حجم بعض الصور دقة شاشة المستخدم ؛ إذا كانت نسبة الارتفاع هو الخطأ, الصورة يجب أن تقطع.قانون بلدي يبدو مثل هذا:

protected void ConvertToBitmap(string filename)
    {
        var origImg = System.Drawing.Image.FromFile(filename);
        var widthDivisor = (double)origImg.Width / (double)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
        var heightDivisor = (double)origImg.Height / (double)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
        int newWidth, newHeight;

        if (widthDivisor < heightDivisor)
        {
            newWidth = (int)((double)origImg.Width / widthDivisor);
            newHeight = (int)((double)origImg.Height / widthDivisor);
        }
        else
        {
            newWidth = (int)((double)origImg.Width / heightDivisor);
            newHeight = (int)((double)origImg.Height / heightDivisor);
        }

         var newImg = origImg.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
        newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
    }

في معظم الحالات, هذا يعمل بشكل جيد.ولكن بعض الصور ، ونتيجة له للغاية نوعية رديئة.يبدو أنه قد تم تغيير حجمها إلى شيء صغير جدا (حجم الصورة المصغرة) و تضخم مرة أخرى..ولكن القرار من الصورة هو الصحيح.ماذا يمكنني أن أفعل ؟

مثال الاصليه صورة:النص البديل http://img523.imageshack.us/img523/1430/naturaerowoods.jpg

مثال على تغيير حجم الصورة:alt text

ملاحظة:يجب تطبيق WPF ولكن يمكنني استخدام WinForms وظيفة تغيير الحجم لأنها أسهل لأنني بالفعل بحاجة إشارة إلى النظام.يقوم نظام ويندوز.أشكال على أيقونة صينية.

هل كانت مفيدة؟

المحلول

تغيير آخر سطرين من أسلوب هذا:

var newImg = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(newImg);
g.DrawImage(origImg, new Rectangle(0,0,newWidth,newHeight));
newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
g.Dispose();

نصائح أخرى

لا أستطيع خاطفة .صافي المصدر في هذه اللحظة, ولكن على الأرجح المشكلة في Image.GetThumbnailImage الأسلوب.حتى MSDN يقول أنه "يعمل بشكل جيد عندما طلبت صورة مصغرة بحجم حوالي 120 × 120 بكسل ، لكنه طلب كبير صورة مصغرة (على سبيل المثال ، 300 × 300) من صورة مضمنة المصغرة, يمكن أن يكون هناك فقدان ملحوظ في جودة الصورة المصغرة".صحيح تغيير حجم (أيلا تصغير), يجب عليك استخدام Graphics.DrawImage الأسلوب.قد تحتاج أيضا إلى اللعب مع Graphics.InterpolationMode للحصول على نوعية أفضل إذا لزم الأمر.

إذا كنت لا إنشاء صورة مصغرة ، باستخدام طريقة تسمى GetThumbnailImage ربما ليست فكرة جيدة...

عن خيارات أخرى ، إلقاء نظرة على هذه المادة CodeProject.ولا سيما أنه يخلق صورة جديدة ، يخلق Graphics و يحدد الاستيفاء وضع HighQualityBicubic وتوجه الصورة الأصلية على الرسومات.يستحق المحاولة على الأقل.

كما هو مبين على MSDN, GetThumbnailImage() لا التعسفي حجم الصورة.أي شيء أكثر من 120x120 ينبغي تحجيم يدويا.جرب هذا بدلا من ذلك:

using(var newImg = new Bitmap(origImg, newWidth, newHeight))
{
    newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
}

تحرير

نقطة توضيح هذا الزائد Bitmap منشئ المكالمات Graphics.DrawImage, ، على الرغم من أنك لم يكن لديك أي سيطرة على الاستيفاء.

بدلا من هذا القانون:

newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);

استخدام هذا واحد :

System.Drawing.Imaging.ImageCodecInfo[] info = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
System.Drawing.Imaging.EncoderParameters param = new System.Drawing.Imaging.EncoderParameters(1);
param.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
newImg.Save(dest_img, info[1], param);

للحصول على أمثلة ، الأصلي صورة JPG و تغيير حجم الصور بابوا نيو غينيا.هل تحويل بين صيغ عمدا ؟ التبديل بين مختلف lossey مخططات ضغط يمكن أن يسبب فقدان الجودة.

هل زيادة أو تقليل حجم الصورة عند تغيير حجم ذلك ؟ إذا كنت تقوم بإنشاء صورة أكبر من أصغر واحد, هذا النوع من التدهور المتوقع.

الصور سوف تكون بالتأكيد المتدهورة إذا كنت تكبير لهم.

بعض الكاميرا وضع تغيير حجم الصور المصغرة في الملف نفسه يفترض لأغراض المعاينة على الجهاز نفسه.

على GetThumbnail طريقة يحصل في الواقع هذه صورة مصغرة والتي هي جزء لا يتجزأ ضمن ملف الصورة بدلا من الحصول على أعلى res الأسلوب.

الحل سهل هو خدعة .صافي في رمي هذا المصغرة المعلومات قبل القيام الخاص بك تغيير حجم أو عملية أخرى.مثل ذلك....

img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX); 
//removes thumbnails from digital camera shots
img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);

إذا كنت تحاول تغيير حجم تقييد نسب كتبت امتداد الأسلوب على النظام.الرسم.الصورة التي قد تجدها مفيدة.

/// <summary>
/// 
/// </summary>
/// <param name="img"></param>
/// <param name="size">Size of the constraining proportion</param>
/// <param name="constrainOnWidth"></param>
/// <returns></returns>
public static System.Drawing.Image ResizeConstrainProportions(this System.Drawing.Image img,
    int size, bool constrainOnWidth, bool dontResizeIfSmaller)
{
    if (dontResizeIfSmaller && (img.Width < size))
        return img;
    img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX); 
    img.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipX);
    float ratio = 0;
    ratio = (float)img.Width / (float)img.Height;

    int height, width = 0;
    if (constrainOnWidth)
    {
        height = (int)(size / ratio);
        width = size;
    }
    else
    {
        width = (int)(size * ratio);
        height = size;
    }
    return img.GetThumbnailImage(width, height, null, (new System.IntPtr(0)));
}

هذا سوف تختلف على نطاق واسع على أساس العوامل التالية:

  1. كيف عن كثب الوجهة القرار المباريات "الطبيعي" على نطاق القرار الأصلي ،
  2. مصدر الصورة عمق اللون
  3. صورة نوع(s) - بعض أكثر الضياع من غيرها
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top