ใช้ mogrify เพื่อปรับขนาดไฟล์ขนาดใหญ่ในขณะที่ไม่สนใจไฟล์ขนาดเล็ก


10

ฉันใช้คำสั่งต่อไปนี้:

mogrify -resize '400x400>' *.png

สังเกตเห็น ">" สมมุติว่ามันจะไม่สนใจไฟล์ที่มีขนาดเล็กกว่า แต่ถึงแม้ว่ามันจะไม่ปรับขนาดมันก็จะทำการแก้ไข (วันที่แก้ไขและขนาดไฟล์จะเปลี่ยนไป)

มีวิธีทำให้จริงเพียงแค่ปล่อยไฟล์ขนาดเล็กเพียงอย่างเดียวหรือไม่ ฉันต้องการหลีกเลี่ยงการเขียนที่ไม่จำเป็นหลายพันครั้ง

คำตอบ:


15

ฉันคิดว่าmogrifyการเขียนไฟล์ใหม่อย่างเป็นระบบดังนั้นความหวังเดียวของคุณคือการกรองรายการก่อนตามที่ jippieแนะนำ นี่คือวิธีที่คุณจะทำได้ (ไม่ได้รับการทดสอบ): พิมพ์รายการไฟล์ภาพด้วยตัวบ่งชี้ขนาดเก็บเฉพาะชื่อที่มีขนาดที่เกี่ยวข้องอยู่ในช่วงและประมวลผลรายการนั้น

identify -format '%w %h %i\n' ./*.png |
awk '$1 > 400 || $2 > 400 {sub(/^[^ ]* [^ ]* /, ""); print}' |
tr '\n' '\0' |
xargs -0 mogrify -resize '400x400'

คำอธิบายสคริปต์:

  • สำหรับแต่ละไฟล์ให้พิมพ์บรรทัดที่มีความกว้างช่องว่างความสูงช่องว่างและชื่อไฟล์ ทั้งนี้ขึ้นอยู่กับรุ่นของคุณidentifyที่\nจะเพิ่มขึ้นบรรทัดสุดท้ายทั้งอาจมีความจำเป็น (ImageMagick 6.6.0) หรือฟุ่มเฟือย แต่ไม่เป็นอันตราย (GraphicsMagick 1.1.11)
  • ( awk) ในแต่ละบรรทัดหากความกว้าง ( $1) และความสูง ( $2) ตรงกับเงื่อนไขที่ต้องการแล้ว:
    • ลบข้อความทั้งหมดจนถึงอักขระช่องว่างที่สอง แถบนี้มีความกว้างและความสูง
    • พิมพ์สิ่งที่เหลืออยู่ของบรรทัดซึ่งเป็นชื่อไฟล์
  • แทนที่บรรทัดใหม่ด้วยอักขระ null
  • โทรxargs -0เพื่อรันmogrifyคำสั่งกับชื่อไฟล์ (เราไม่สามารถใช้ธรรมดาได้xargsเพราะไม่สามารถจัดการกับอินพุตที่มีช่องว่างหรือ\'")

ชื่อไฟล์อาจมีอักขระใด ๆ ยกเว้นการขึ้นบรรทัดใหม่


คุณอธิบายสคริปต์นั้นได้ไหม โดยเฉพาะส่วน "ย่อย" มันกำลังพิมพ์ชื่อไฟล์โดยไม่ต้องเว้นวรรคหรือแทรกบรรทัดใหม่ mogrify: ไม่สามารถเปิดไฟล์ `22 553.png308 400 0134 2.png '@ error / png.c / ReadPNGImage / 2951 ฉันไม่รู้ว่าที่ "308 400" มาจากไหน ฉันควรพูดถึงไฟล์ที่มีช่องว่างในชื่อของพวกเขาขอบคุณ
Mike

ฉันได้รับ mogrify: ไม่สามารถเปิดไฟล์ `340 271 22 553.png308 400 0134 2.png '@ error / png.c / ReadPNGImage / 2951 ฉันรันคำสั่งโดยใช้ 200x200 ในสองไฟล์ตัวอย่าง ฉันเห็นว่า 308x400 เป็นขนาดหนึ่งในไฟล์
Mike

2
@ ไมค์อ่าเข้าใจแล้ว บางรุ่นidentifyวางบรรทัดใหม่หลังจากแต่ละเร็กคอร์ดส่วนอื่น ๆ ต้องมีหนึ่งบรรทัดอย่างชัดเจน เพิ่ม\nในตอนท้ายของอาร์กิวเมนต์เพื่อ-format(ดูการแก้ไขของฉัน)
Gilles 'หยุดความชั่วร้าย' ใน

8

ฉันประสบปัญหาเดียวกันกับที่คุณอธิบาย นี่คือทางออกของฉัน:

#!/bin/bash
files=*.jpg
minimumWidth=640
minimumHeight=640

for f in $files
do
    imageWidth=$(identify -format "%w" "$f")
    imageHeight=$(identify -format "%h" "$f")

    if [ "$imageWidth" -gt "$minimumWidth" ] || [ "$imageHeight" -gt "$minimumHeight" ]; then
        mogrify -resize ''"$minimumWidth"x"$minimumHeight"'' $f
    fi
done

ฉันทดสอบกับภาพ JPEG หลายภาพบนเครื่อง CentOS 6.5 แบบเสมือนจริง สคริปต์จะปรับขนาดและบีบอัดภาพที่มีความกว้างหรือความสูงมากกว่า 640 พิกเซลเท่านั้น สิ่งนี้ทำให้การทำงานกับภาพที่มีขนาดเช่น 800 x 600 (แนวนอนปรับขนาดเป็น 640 x 480) และขนาดเช่น 600x800 (แนวตั้งปรับขนาดเป็น 480 x 640)

PS: หมายเหตุเกี่ยวกับ400x400พารามิเตอร์: mogrifyจะประมวลผลไฟล์แม้ว่าขนาดจะเท่ากันหรือเล็กกว่า 400x400 แต่จะปรับขนาดเฉพาะเมื่อขนาดมีขนาดใหญ่กว่า 400x400 นั่นเป็นสาเหตุที่เวลาและขนาดการเปลี่ยนแปลงของไฟล์เปลี่ยนแปลง (ในกรณีของฉันmogrifyทำให้ไฟล์เหล่านี้มีขนาดใหญ่กว่าเดิม)


5

คุณสามารถใช้fxโอเปอเรเตอร์เพื่อกรองภาพตามความสูง / ความกว้างเช่น

identify -format '%[fx:(h>400 && w>400)]\n' image.png

จะออก1หากภาพมีขนาดใหญ่กว่า400x400และ0ถ้ามันมีค่าเท่ากับหรือเล็กกว่า400x400...


สมมติว่าชื่อไฟล์มีเหตุผล (ไม่มีการขึ้นบรรทัดใหม่ / ช่องว่าง / แท็บ ฯลฯ ) คุณสามารถใช้identifyเพื่อพิมพ์ชื่อภาพนำหน้าด้วย1:หรือ0:ดำเนินการลบบรรทัดที่เริ่มต้นด้วย0:การลบและนำ1:ส่วนที่เหลือของบรรทัดเพื่อให้ชื่อไฟล์ยังคงอยู่ ต่อบรรทัดจากนั้นไพพ์ไปยังรายการที่ต้องการmogrify ... @-( เพิ่ม@ไวยากรณ์imagemagick v6.5.2 ):

identify -format '%[fx:(h>400 && w>400)]:%i\n' ./*.png | \
sed '/^1:/!d;//s///' | mogrify -resize '400x400' -- @-

มิฉะนั้นfindคุณสามารถพิมพ์เฉพาะไฟล์ที่มีขนาด> 400x400 แล้วไปป์ผลลัพธ์ที่xargs+ mogrify(มีประสิทธิภาพน้อยกว่าเพราะมันรันเชลล์สำหรับแต่ละไฟล์ แต่ควรทำงานกับชื่อไฟล์ทุกชนิด):

find . -maxdepth 1 -type f -name '*.png' -exec sh -c \
'identify -format "%[fx:(h>400 && w>400)]\n" "$0" | grep -q 1' {} \; -print0 \
| xargs -0 mogrify -resize '400x400'

หากคุณเป็นzshผู้ใช้เห็นคำตอบนี้ด้วย


3

วิธีใช้การระบุเพื่อค้นหาขนาดของรูปภาพและตัดสินใจจากสคริปต์ขนาดเล็กถ้าคุณต้องการแก้ไขหรือไม่:

identify -format "width=%w heigth=%h" bootchart.png 
width=3853 heigth=10092

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


เมื่อพิจารณาถึงทักษะที่ จำกัด ของฉันและความจริงที่ว่าขนาดของรูปภาพนั้นไม่สม่ำเสมอฉันต้องการวิธีที่ง่ายกว่า ฉันต้องการประมวลผลพวกเขาทั้งหมดด้วยความโมโห
Mike

0

ฉันใช้ PHP-script เช่นนั้นมันใช้ ImageMagick:

<?php
$dir = ".";
$exts = array('jpg', 'jpeg', 'png', 'gif');
$max_size = is_numeric($argv[1]) ? $argv[1] : 3000;
$morgify = "mogrify -verbose -scale \"${max_size}x${max_size}>\" -quality 85";
$identify = "identify -format \"%wx%h\"";

$dh = opendir($dir);
while (($file = readdir($dh)) !== false) {
    $path = "$dir/$file";
    // skip no images
    $dot = strrpos($file, '.');
    $ext = strtolower(substr($file, $dot + 1));
    if (!in_array($ext, $exts)) continue;
    // large size?
    $size = exec("$identify \"$path\"");
    list($width, $height) = explode('x', trim($size));
    if (max($width, $height) > $max_size) {
        // scale!
        print "scale $file ${width}x${height}";
        exec("$morgify \"$path\"");
        print "\n";
    }
}
closedir($dh);
?>

มันปรับขนาดภาพทั้งหมดในไดเรกทอรีปัจจุบันที่ใหญ่กว่า 3,000 บนขอบบาง

เรียกใช้คำสั่ง: php scale.phpหรือphp scale.php 2000


0

นี่คือสิ่งที่ฉันทำได้โดยผสมผสานแนวคิดจาก @ArionKrause และ @don_crissti:

#!/bin/bash
# adapted from http://unix.stackexchange.com/a/157594/110635
# and http://unix.stackexchange.com/a/220619/110635
W=1024
H=768
SIZE_TEST="%[fx:(h>$H && w>$W)]"'\n'

for f in $*; do
  if [ $(identify -format "$SIZE_TEST" "$f") = 1 ]; then
    echo "Resize: $f"
    mogrify -resize ''"$W"x"$H"'' "$f"
  else
    echo "Do not resize: $f"
  fi
done

(ฉันต้องการสิ่งนี้เพราะชุดโปรเซสเซอร์โปรดของฉัน Phatch ไม่ทำงานกับ Ubuntu 16.04)


0

ฟังก์ชั่นของฉันเพื่อปรับขนาดและเพิ่มประสิทธิภาพ

resize_and_optimize_images () {
  resize_images 700 $PWD
  optimize_images 85 $PWD
}

resize_images () {
  max="$1"
  dir="$2"

  echo "Resizing dir $dir, max size - $max"

  shopt -s globstar

  for f in $dir/**/*.jpg $dir/**/*.jpeg $dir/**/*.png ; do
    echo "Checking $f"
    s=`identify -format "%w" $f`

    if [ $s -gt $max ]; then
      echo "Resizing..."
      mogrify -verbose -resize $max $f
    fi
    echo
  done

  echo "Done resizing dir $dir"
}

optimize_images () {
  quality="$1"
  dir="$2"

  echo "Optimizing dir $dir, quality - $quality"

  docker run -it --rm --name optimize_images_foo \
    -v $dir:/usr/src/app \
    -w /usr/src/app ruby:2.4-stretch bash -c \
    "gem install image_optim image_optim_pack && \
    (curl -L \"http://static.jonof.id.au/dl/kenutils/pngout-20150319-linux.tar.gz\" | tar -xz -C /usr/bin --strip-components 2 --wildcards \"*/x86_64/pngout\") && \
    image_optim --verbose --allow-lossy --jpegoptim-allow-lossy true --jpegoptim-max-quality $quality --pngquant-allow-lossy true --pngquant-quality 0..$quality -r ."

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