จัดเรียงภาพตามอัตราส่วน


13

ฉันพยายามเลือกภาพศิลปะสองสามภาพเพื่อให้พอดีกับเฟรมใหม่บางเฟรม ฉันต้องการที่จะสามารถจัดเรียงภาพเหล่านี้ตามอัตราส่วนใกล้เคียงกับอัตราส่วนเฉพาะแล้วดูพวกเขาในการลดลำดับความใกล้ชิดผ่านสิ่งที่ชอบ feh

มีการแสดงออก Unix บรรทัดเดียวที่รุ่งโรจน์หรือไม่? มิฉะนั้นสองสามบรรทัดของ Python ควรจะเคลียร์สิ่งนี้


3
คุณสามารถดึงอัตราส่วนผ่าน ImageMagick identify -format "%[fx:w/h]:%M\n" *.jpgเช่น ฉันไม่ทราบวิธีการเรียงลำดับความใกล้เคียงกับค่าโดยพลการได้อย่างง่ายดาย sortดูเหมือนจะไม่สนับสนุนการเรียงลำดับดังกล่าว
NN

โดยพื้นฐานแล้วคุณต้องการแปลงตัวเลขเหล่านี้เป็นตัวชี้วัดระยะทางจำนวนเต็มจากนั้นคุณสามารถส่งมันให้เรียงลำดับ -n ได้ ดูเหมือนว่าคุณจะสามารถทำคณิตศาสตร์ทั้งหมดด้วย ImageMagick
Derobert

คำตอบ:


8

การใช้ความคิดเห็น ImageMagick ของ NN เป็นโอกาสในการขายมันกลายเป็นว่าคุณสามารถให้มันทำการคำนวณโดยพลการซึ่งเป็นส่วนหนึ่งของ-formatผลลัพธ์ ดังนั้นวิธีหนึ่งที่เป็นไปได้:

identify -format "%[fx:round(100000*abs((4/3)-(w/h)))]:%M\n" *.jpg | \
    sort -n -k1 -t:

ควรทำสิ่งที่คุณต้องการ โปรดทราบว่า 4/3 มีค่าคงที่อัตราส่วนภาพที่ต้องการ แน่นอนคุณสามารถพบว่าเป็นผลลัพธ์ของหน้าที่แล้วidentify(เพื่อจับคู่ "ใกล้เคียงกับภาพนี้")

เพื่ออธิบายว่าเราได้รับความแตกต่างอย่างชัดเจนระหว่างสัดส่วนภาพที่ต้องการและตามจริง จากนั้นคูณด้วยจำนวนมากและปัดเศษ การคูณและปัดเศษเป็นเพราะการเรียงลำดับจัดการเฉพาะจำนวนเต็มไม่ใช่ปันส่วน

แก้ไข

ปรากฎsortว่าดูเหมือนจะทำปันส่วนไม่ใช่แค่จำนวนเต็ม แม้จะระบุไว้ในข้อมูลจำเพาะ Unix เดี่ยว (v4) ดังนั้นคุณสามารถกำจัดวิธีแก้ปัญหานั้นได้:

identify -format "%[fx:abs((4/3)-(w/h))]:%M\n" *.jpg | \
    sort -n -k1 -t:

คุณพบเอกสารของตัวเลือก - รูปแบบที่ระบุได้จากที่ใด ฉันไม่เห็นอะไรเลยในหน้า man และใช้เวลาพอสมควรในการหาคำตอบออกมา
terdon

โอ้และในระบบของฉันคำสั่งของคุณดูเหมือนจะไม่ทำงาน ฉันได้33333:cover.jpgที่ cover.jpg คือ 500x500
terdon

2
@terdon ดีนั่นเป็นเพราะมันมีอัตราส่วน 1/1 ไม่ใช่ 4/3 4 / 3-1 = 1/3 = .333 …. เพียงเปลี่ยนอัตราส่วน 4/3 ให้เป็นอัตราส่วนที่คุณต้องการ (ซึ่งฟังดูเหมือน 1/1) เอกสารอยู่ที่imagemagick.org/script/fx.phpในลักษณะที่สับสนโดยทั่วไป เอาฉันสักครู่เพื่อหาพวกเขาเช่นกัน
Derobert

ขอบคุณสำหรับลิงค์ ส่วนที่เหลือฉันเป็นคนงี่เง่า ฉันมี jpg เพียงหนึ่งไฟล์ในโฟลเดอร์ทดสอบของฉัน (ส่วนที่เหลือเป็น pngs) ดังนั้นเนื่องจากฉันเห็นบรรทัดเอาต์พุตเพียงบรรทัดเดียวฉันจึงสันนิษฐานว่าเป็นผลลัพธ์ที่ต้องการและตัวระบุนั้นอ้างว่าภาพนั้นมีอัตราส่วนภาพ 4/3 นั่นคือสิ่งที่ฉันพยายามคิดตอนเย็นวันจันทร์ ... +1 สำหรับคำตอบที่สง่างาม
terdon

คำตอบที่ดี! มีวิธีใดที่จะผนวกป้ายกำกับบางประเภทไว้ในชื่อไฟล์ของภาพทั้งหมดที่ไม่ได้ปฏิบัติตามอัตราส่วนที่ต้องการหรือไม่
Mentalist

3

ด้วยวิธีที่ง่ายที่สุดในการทำเช่นนี้จะใช้ImageMagick มันควรจะอยู่ในที่เก็บของการกระจาย Linux ของคุณสำหรับระบบที่ใช้เดเบียนให้รัน:

sudo apt-get install imagemagick

หนึ่งในโปรแกรมของชุด ImageMagick คือidentifyนี่จะพิมพ์คุณสมบัติของรายการไฟล์ภาพเข้า การรวมเข้ากับsortจะให้รายการรูปภาพที่เรียงตามขนาด (คุณสามารถเปลี่ยน png สำหรับนามสกุลที่คุณมี:

identify *png | sort -gk 3

หากคุณต้องการอัตราส่วนจริงและไม่ใช่แค่ขนาดลองสิ่งนี้:

  1. ตัวเลือกที่ง่ายสมมติว่าชื่อภาพของคุณไม่มีช่องว่าง :

    identify *png *jpg *gif | \
    gawk '{split($3,sizes,"x"); print $1,sizes[1]/sizes[2]}' | \
    sed 's/\[.\]//' | sort -gk 3
    

    คำสั่ง gawk แยกฟิลด์ที่ 3 (ขนาดรูปภาพที่มีรูปแบบ LxH) ลงในอาร์เรย์ "ขนาด" แล้วพิมพ์ฟิลด์ที่ 1 (ชื่อรูปภาพ) และผลลัพธ์ของการหารความยาวของรูปภาพตามความสูงของมัน sedคำสั่งเป็นเพียงความงามที่ส่งออกและsortคำสั่งเรียงลำดับผลตามอัตราส่วนขนาดของภาพ

  2. ซับซ้อนมากขึ้นอันนี้สามารถจัดการกับช่องว่างในชื่อไฟล์:

    find . \( -iname  "*png" -o -iname "*jpg" -o -iname "*gif" \) -exec identify {} \; |\
    perl -ne '/(.+?)\s+[A-Z]{3}\s+(\d+)x(\d+)/; print "$1 ", $2/$3, "\n"' | \
    sort -gk 2
    

    ที่นี่เราใช้findเพื่อระบุไฟล์ที่เราสนใจและรันidentifyคำสั่งจากนั้นไพพ์เอาต์พุตของมันผ่านสคริปต์ PERL เล็กน้อย นิพจน์ทั่วไปค้นหาอักษรตัวใหญ่สามตัว ( [A-Z]{3}) ซึ่งควรเป็นรูปแบบภาพ เมื่อเราพบว่ามันเป็นเรื่องง่ายที่จะระบุชื่อภาพและขนาด

    ฉันไม่ได้ใช้เพ่งพิศที่นี่เพราะการปรากฏตัวของช่องว่างในชื่อไฟล์อินพุตจะสับสนหมายเลขฟิลด์ ในที่สุดสคริปต์จะพิมพ์ชื่อของภาพและผลลัพธ์ของการแบ่งความยาว / ความสูงที่เราsortเป็นตัวเลข

หากการเรียกดูอัตราส่วนภาพที่มีอยู่ไม่เพียงพอหากคุณมีภาพอย่างน้อยหนึ่งภาพที่มีอัตราส่วนภาพที่ต้องการเพียงใช้ grep เพื่อแยกภาพเหล่านั้นซึ่งมีอัตราส่วนใกล้เคียงที่สุด:

identify *png *jpg *gif | \
gawk '{split($3,sizes,"x"); print $1,sizes[1]/sizes[2]}' |\
sed 's/\[.\]//' | sort -gk 3 | grep -C 10 GOOD_IMAGE.jpg

2

คุณสามารถคำนวณความแตกต่างของอัตราส่วนแต่ละภาพด้วยการอ้างอิง ดูเหมือนคำตอบของ Derobert แต่เรียบง่ายกว่า:

ref=4/3
identify -format "%[fx:abs(w/h - $ref)] %M\n" *.jpg | sort -n -k1

อืมดูเหมือนว่าการจัดเรียงจะทำหน้าที่ปันส่วน ผมก็รู้สึกว่ามันไม่ได้ ...
derobert

2

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

ผู้ชมต่อไปนี้ทำงานได้ตามที่คาดไว้ ( fehไม่ได้ส่งต่อ / ย้อนกลับแม้สำหรับภาพจริง - ในระบบของฉัน)

  • Comix
  • eog (Eye of Gnome / โปรแกรมดูรูปภาพ)
  • gwenview

picd='/media/dat_ext4/pictures/jpg/misc'
srtd="$picd/ar-sort"   # directory to hold "sorted" symbolic links
mkdir -p "$srtd"              

find "$picd" -maxdepth 1 -type f -name "*" -print0 | 
  while IFS= read -d $'\0' -r file ; do
    [[ $(file -ib "$file") != image* ]] && continue  # skip non-image files
    ar="$(identify -format "%[fx:w/h]" "$file")"  
    slink="$(printf '%s/%06.4f %s' "$srtd" "$ar" "$(basename "$file")")"
    # make symbolic link in 'ar-sort' directory
    ln -s "$file" "$slink"  
    echo "$slink" 
  done 

ไปที่ไดเรคทอรีar-sortและเพียงเรียกดูจากจุดเริ่มต้น (อัตราส่วนกว้างยาว) ที่คุณสนใจ

ชื่อลิงก์สัญลักษณ์มีลักษณะดังนี้:

0.6732 Gold Bars.jpg
0.7242 Light Bulb.jpg
0.8022 Escher - Waterfall.jpg
1.3696 Old Typewriter.jpg
1.6000 King Tut.jpg

หมายเหตุ: หากการตั้งค่าโลแคลของคุณใช้เครื่องหมายทศนิยมอื่นที่ไม่ใช่จุดจะไม่สามารถใช้งานได้ ง่ายต่อการแก้ไข: stackoverflow.com/questions/12845997/…
Jobjörn Folkesson

1

บรรทัดการให้เหตุผลตามปกติของฉันคือการใช้การวัดระยะห่างข้อผิดพลาดกำลังสองทุกที่ที่ฉันได้ยินคำว่า "ระดับความใกล้ชิด" เราสามารถใช้ค่าสัมบูรณ์และมันจะเร็วขึ้น สคริปต์ใช้เป็นอาร์กิวเมนต์ในอัตราส่วนภาพในอุดมคติประมวลผลไฟล์ * .jpg ทั้งหมดในไดเรกทอรีปัจจุบันและส่งออกเรียงตามลำดับที่เพิ่มขึ้นของความแตกต่างจากอัตราส่วนในอุดมคติ

head ลบอักขระท้ายบรรทัดที่ต่อท้ายที่แทรกโดย ImageMagick

สคริปต์มีคำสั่ง gawk ซึ่งตั้งค่าตัวคั่นฟิลด์ผลลัพธ์เป็นอักขระที่ไม่น่าคำนวณคำนวณความแตกต่างยกกำลังสองและพิมพ์ชื่อไฟล์ เรียงจะดำเนินการและข้อมูลที่ไม่จำเป็น (ด้าน Squared อัตราส่วนที่แตกต่างกัน) cutจะคัดมาจาก

#!/bin/sh
if [ x"$1" = "x" ] ; then
  echo "Usage: $0 TargetAspectRatio" >&2
  exit 2
fi
ASPECT_CMD="BEGIN{OFS=\"|\";}\
{\
print (\$1-$1)^2, \$2;\
}"
identify -format "%[fx:w/h]:%M\n" *.jpg | head -n-1 | gawk -F":" "$ASPECT_CMD" | sort -k1 -t"|" | cut -f2 -d"|"

โปรดทราบว่ามันใช้ระยะทางกำลังสองและการคำนวณภายใน gawk / awk :) (ขอบคุณ @NN สำหรับทางลัดเริ่มต้น)
Deer Hunter

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