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

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

سؤال

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

alt text

لذلك، كيف يمكنني اقتصاص / إنشاء إصدارات قياسية بحجم معيار من الصورة دون إظهار التحليل أعلاه؟

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

المحلول

حسنا، يجب أن يكون لديك أقصى ارتفاع وعرض، يتيح لك افتراض حجم الصورة الذي توفره هو مربع، قل 100x100.

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

ثم تأخذ أعظم القياس واحصل على نسبة هذا القياس إلى القياس المستهدف، ثم استخدم تلك النسبة لتوسيع نطاق الطول والعرض.

لذلك إذا قام المستخدم بتحميل صورة 500 ارتفاع و 450 عرض، حيث أن الارتفاع أعظم تقسيم 100 بنسبة 500، حجم الصورة المصغرة الخاصة بك. هذا يعطينا .2 كنسبة. مما يعني أن العرض سيصبح 90، لذلك سوف تتقلص إلى 100x90، ولا يحدث أي تشويه.

نصائح أخرى

إليك بعض الكود (C #) اعتدت أن أفعل تغيير حجمها، مماثلة للطريقة التي اقترحتها ضربة عنيفة. ما عليك سوى استبدال "300" بالحجم القصوى من جانب واحد في قضيتك:

 private Bitmap ScaleImage(Image oldImage)
    {
        double resizeFactor = 1;

        if (oldImage.Width > 300 || oldImage.Height > 300)
        {
            double widthFactor = Convert.ToDouble(oldImage.Width) / 300;
            double heightFactor = Convert.ToDouble(oldImage.Height) / 300;
            resizeFactor = Math.Max(widthFactor, heightFactor);

        }
        int width = Convert.ToInt32(oldImage.Width / resizeFactor);
        int height = Convert.ToInt32(oldImage.Height / resizeFactor);
        Bitmap newImage = new Bitmap(width, height);
        Graphics g = Graphics.FromImage(newImage);
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        g.DrawImage(oldImage, 0, 0, newImage.Width, newImage.Height);
        return newImage;
    }

أو: إذا كنت لا تزال تحب الأبعاد الثابتة، فإنك تتبع تعليمات Blowdart لكنها حساب أكبر نسبة بدلا من ذلك: 100px / 450px = .22 ..

  • العرض: 100px.
  • الارتفاع: 111.11..px -> المحاصيل من الكلمة ((111.11 - 100) / 2) في الأعلى و 100px أسفل.

تعديل: أو دع المستخدم حدد كيفية اقتصاص أعظم البعد.

يستخدم Imagemagick.. وبعد في سطر الأوامر، استخدم:

convert -thumbnail geometry

لقد قمت بإجراء هذه الوظيفة ل PHP منذ فترة أن تعمل بشكل رائع لهذا وبعض السيناريوهات الأخرى:

<?php

function Image($source, $crop = null, $resize = null)
{
    $source = ImageCreateFromString(file_get_contents($source));

    if (is_resource($source) === true)
    {
        $width = imagesx($source);
        $height = imagesy($source);

        if (isset($crop) === true)
        {
            $crop = array_filter(explode('/', $crop), 'is_numeric');

            if (count($crop) == 2)
            {
                if (($width / $height) > ($crop[0] / $crop[1]))
                {
                    $width = $height * ($crop[0] / $crop[1]);
                    $crop = array((imagesx($source) - $width) / 2, 0);
                }

                else if (($width / $height) < ($crop[0] / $crop[1]))
                {
                    $height = $width / ($crop[0] / $crop[1]);
                    $crop = array(0, (imagesy($source) - $height) / 2);
                }
            }

            else
            {
                $crop = array(0, 0);
            }
        }

        else
        {
            $crop = array(0, 0);
        }

        if (isset($resize) === true)
        {
            $resize = array_filter(explode('*', $resize), 'is_numeric');

            if (count($resize) >= 1)
            {
                if (empty($resize[0]) === true)
                {
                    $resize[0] = round($resize[1] * $width / $height);
                }

                else if (empty($resize[1]) === true)
                {
                    $resize[1] = round($resize[0] * $height / $width);
                }
            }

            else
            {
                $resize = array($width, $height);
            }
        }

        else
        {
            $resize = array($width, $height);
        }

        $result = ImageCreateTrueColor($resize[0], $resize[1]);

        if (is_resource($result) === true)
        {
            ImageCopyResampled($result, $source, 0, 0, $crop[0], $crop[1], $resize[0], $resize[1], $width, $height);
            ImageDestroy($source);

            header('Content-Type: image/jpeg');

            ImageJPEG($result, null, 90);
            ImageDestroy($result);
        }
    }

    return false;
}

Image('/path/to/your/image.jpg', '1/1', '100*');
Image('/path/to/your/image.jpg', '1/1', '100*100');
Image('/path/to/your/image.jpg', '1/1', '100*500');

?>

إليك أمر باش أخرجت معا لإنجاز هذا باستخدام أداة تحويل ImageMagick. لمجموعة من الصور التي تجلس في الدليل الأصلي، بعض الصور، بعض المناظر الطبيعية، لإنشاء صور في الدليل الحالي تحجيمها إلى 600 × 400، صور صورة اقتصاص من المركز ومجرد تحجيم صور المناظر الطبيعية:

for f in ../*jpg; do
    echo $f; 
    size=`identify $f|cut -d' ' -f 3`; 
    w=`echo $size|cut -dx -f 1`; 
    h=`echo $size|cut -dx -f 2`; 
    if [ $w -gt $h ]; then 
        convert $f -thumbnail 600x400 `basename $f`; 
    else 
        convert $f -scale 600x -crop 600x400+0+`echo "((600*($h/$w))/2)" | bc | sed 's/\..*//'` `basename $f`; 
    fi;
done;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top