Cut image in horizontal slices

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
godfried76
Posts: 6
Joined: 2019-06-12T03:27:00-07:00
Authentication code: 1152

Cut image in horizontal slices

Post by godfried76 »

Hi,

I'm new to ImageMagick and hope someone could help me. I'm looking for a command / script which could automatically split an image with music score into smaller image files with the individual bars.

So somehow, the programme should detect horizontal bars with all white pixels. Those are the places where the image can be "chopped" into pieces.

Source file:
Image

Resulting files:
Image

Image

Image

Image

Can anybody please help me? Thanks!

Mathias
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Cut image in horizontal slices

Post by snibgo »

What verson of IM, on what platform? I have Windows BAT scripts for this at Subimage rectangles . I think Fred has bash scripts for this at http://www.fmwconcepts.com/imagemagick/index.html
snibgo's IM pages: im.snibgo.com
godfried76
Posts: 6
Joined: 2019-06-12T03:27:00-07:00
Authentication code: 1152

Re: Cut image in horizontal slices

Post by godfried76 »

Windows.

Impressive collection of BAT-files you have there. I'll take a look. Thanks!
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Cut image in horizontal slices

Post by fmw42 »

One way is to average your images down to 1 column. Then scan the column for the middle of pure white (or max gray level) and split there. You will have to combine the titles back with the first bar.
godfried76
Posts: 6
Joined: 2019-06-12T03:27:00-07:00
Authentication code: 1152

Re: Cut image in horizontal slices

Post by godfried76 »

In the end, I couldn't get the bat-scripts to work. Always error messages.

So I installed a linux virtual machine and used this script, which I found on the forum. It NEARLY does what I want!

#!/bin/bash

cd ~
cd Afbeeldingen
WxH=`convert 043-lg.jpg -format "%wx%h" info:`
cropArr=(`convert 043-lg.jpg -blur 0x3 \
-scale 1x! -scale ${WxH}! \
-negate -threshold 0% -negate \
-type bilevel \
-define connected-components:verbose=true \
-connected-components 4 null: | grep "gray(0)" | awk '{print $2}'`)
num=${#cropArr[*]}
for ((i=0; i<num; i++)); do
j=$((i+1))
jj=`printf %02d $j`
convert 043-lg.jpg -crop "${cropArr[$i]}" +repage -bordercolor white -border 0 image_line_$jj.jpg
done

There is, however, 1 problem, which is hopefully very easy to solve...

The slices are all mixed up! I.e. to put the picture together again, I need to start with 06, then 04, then 03, 02, 01, 05. I don't even see a pattern here... Why doesn't it number my slices from top to bottom?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Cut image in horizontal slices

Post by fmw42 »

-connected components list regions from largest to smallest. So you will need to filter on the bounding box Y coordinate to sort in top to bottom order.
godfried76
Posts: 6
Joined: 2019-06-12T03:27:00-07:00
Authentication code: 1152

Re: Cut image in horizontal slices

Post by godfried76 »

Thanks for your advice, fmw42!

How would this work? I'm totally new to ImageMagick (and to bash scripting for that matter ;) ) so sorry if this is a trivial question...
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Cut image in horizontal slices

Post by fmw42 »

Please do not post in two places.

Try this with the image you posted. Put it in a folder (I called it testing). In the future, I suggest you do not put spaces in file names. It just makes it harder to process. You must then put quotes about the name.

I make no guarantees that the blur value of 0x4 and the threshold of 1% will work for all images. So you may have adjust.

Code: Select all

cd
cd desktop/testing
infile="Image 002.jpg"
inname=`convert "$infile" -format "%t" info:`
WxH=`convert "$infile" -format "%wx%h" info:`
cropArr=(`convert "$infile" -blur 0x4 \
-scale 1x! -scale ${WxH}! \
-negate -threshold 1% -negate \
-type bilevel \
-define connected-components:verbose=true \
-define connected-components:mean-color=true \
-connected-components 4 null: | grep "gray(0)" | tr "x" "+" | awk '{print $2}'`)
num=${#cropArr[*]}
sort_list=`echo "${cropArr[*]}" | tr " " "\012" | sort -n -t "+" -k4,4`
cropArrSort=($sort_list)
for ((i=0; i<num; i++)); do
j=$((i+1))
jj=`printf %02d $j`
cropval=`echo "${cropArrSort[$i]}" | sed -n 's/^\([^+]*\)[+]\([^+]*\)[+]\([^+]*\)[+]\([^+]*\)$/\1x\2+\3+\4/p'`
convert "$infile" -crop $cropval +repage -bordercolor white -border 2 "${inname}_line_$jj.jpg"
done
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Cut image in horizontal slices

Post by fmw42 »

If you also want the script to append the first 3 items, then try

Code: Select all

cd
cd desktop/testing
infile="Image 002.jpg"
inname=`convert "$infile" -format "%t" info:`
WxH=`convert "$infile" -format "%wx%h" info:`
cropArr=(`convert "$infile" -blur 0x4 \
-scale 1x! -scale ${WxH}! \
-negate -threshold 1% -negate \
-type bilevel \
-define connected-components:verbose=true \
-define connected-components:mean-color=true \
-connected-components 4 null: | grep "gray(0)" | tr "x" "+" | awk '{print $2}'`)
num=${#cropArr[*]}
sort_list=`echo "${cropArr[*]}" | tr " " "\012" | sort -n -t "+" -k4,4`
cropArrSort=($sort_list)
for ((i=0; i<num; i++)); do
cropval=`echo "${cropArrSort[$i]}" | sed -n 's/^\([^+]*\)[+]\([^+]*\)[+]\([^+]*\)[+]\([^+]*\)$/\1x\2+\3+\4/p'`
convert "$infile" -crop $cropval +repage -bordercolor white -border 2 tmp$i.miff
done
for ((i=0; i<$((num-2)); i++)); do
ii=`printf %02d $i`
if [ $i -eq 0 ]; then
convert tmp0.miff tmp1.miff tmp2.miff -append "${inname}_line_$ii.jpg"
else
j=$((i+2))
convert tmp$j.miff "${inname}_line_$ii.jpg"
fi
done
rm -f tmp*.miff
godfried76
Posts: 6
Joined: 2019-06-12T03:27:00-07:00
Authentication code: 1152

Re: Cut image in horizontal slices

Post by godfried76 »

AMAZING!! You are THE BEST!! Thank you so much!!

If anyone else is reading this, I could just add I made some very minor adaptations to the script, indicated in bold.

#!/bin/bash


cd ~
cd Afbeeldingen
infile=$1
inname=`convert "$infile" -format "%t" info:`
WxH=`convert "$infile" -format "%wx%h" info:`
cropArr=(`convert "$infile" -blur 0x3 \
-scale 1x! -scale ${WxH}! \
-negate -threshold 0% -negate \
-type bilevel \
-define connected-components:verbose=true \
-define connected-components:mean-color=true \
-connected-components 4 null: | grep "gray(0)" | tr "x" "+" | awk '{print $2}'`)
num=${#cropArr[*]}
sort_list=`echo "${cropArr[*]}" | tr " " "\012" | sort -n -t "+" -k4,4`
cropArrSort=($sort_list)
for ((i=0; i<num; i++)); do
cropval=`echo "${cropArrSort[$i]}" | sed -n 's/^\([^+]*\)[+]\([^+]*\)[+]\([^+]*\)[+]\([^+]*\)$/\1x\2+\3+\4/p'`
convert "$infile" -crop $cropval +repage -bordercolor white -border 2 tmp$i.miff
done
for ((i=0; i<$((num-2)); i++)); do
ii=`printf %02d $i`
if [ $i -eq 0 ]; then
convert tmp0.miff tmp1.miff tmp2.miff -append "${inname}_line_$ii.jpg"
else
j=$((i+2))
convert tmp$j.miff "${inname}_line_$ii.jpg"
fi
done
rm -f tmp*.miff
Post Reply