1
0
mirror of https://github.com/ssb22/scan-reflow.git synced 2023-06-16 10:02:22 +00:00
scan-reflow/derotate.sh

142 lines
6.3 KiB
Bash

#!/bin/bash
# Script to assist in correcting rotations
# (c) Silas S. Brown 2006-2008,2019-2022, v1.122
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Where to find history:
# on GitHub at https://github.com/ssb22/scan-reflow
# and on GitLab at https://gitlab.com/ssb22/scan-reflow
# and on BitBucket https://bitbucket.org/ssb22/scan-reflow
# and at https://gitlab.developers.cam.ac.uk/ssb22/scan-reflow
# and in China: https://gitee.com/ssb22/scan-reflow
if [ ! "$1" ]; then
echo "Syntax: $0 image-file image-file ....."
echo "Helps you de-rotate all images listed on the command-line."
exit 1
fi
# Remember on cygwin $HOME may have spaces in it
if (cd "$HOME";test -e .gimp*/tmp/*-area.png); then
echo -n "Error: Some saved areas already exist in "
echo -n "$HOME/";cd "$HOME";echo .gimp*/tmp
echo "Please check if they're important, and if not, remove them."
echo "Then run this script again."
exit 1
fi
echo "
About to run gimp on all image files, one by one.
When each file loads, do this:
1. Use the selection tool
2. Choose a line of the rotated text
3. Click on the bottom left of this line
4. Drag to the bottom right of this line
5. Use the 'save area' command to save the selection
6. If the line is slanting upwards, REPEAT step 5
7. Quit the GIMP (Control-Q)
This script will then look at the dimensions of the area you
saved (and whether or not you saved it twice) and will use this
information to calculate the angle of rotation of the image.
The image will then be replaced with its de-rotated version
(and converted to PNG if it's not already PNG).
If any image is straight already, just quit (Control-Q)
and the image will be converted to PNG with no rotation.
Press Enter when you have read the above instructions.
"
read
unset NeedRemove
export TempDirectory=$(mktemp -d)
touch $TempDirectory/.ready
while [ "$1" ]; do
if test -d /cygdrive; then
# looks like we're on CygWin - this is tricky
cp "$1" /cygdrive/c/Program*Files/GIMP*/bin
pushd /cygdrive/c/Program*Files/GIMP*/bin
./gimp*.exe -d -s "$1" || exit 1
#echo "Press Enter when Gimp has terminated" ; read
mv "$1" "$OLDPWD"
popd
else gimp -d -s "$1" || exit 1; fi
NumFiles=$(cd "$HOME";ls .gimp*/tmp/*-area.png 2>/dev/null|wc -l)
export AsPng="$(echo "$1"|sed -e 's/\.[^\.]*$/.png/')"
if ! echo "$1"|grep '\.' >/dev/null; then export AsPng="$1.png"; fi # (if no extension at all)
if test $NumFiles == 0; then
# it seems this one was straight. but we might still have to convert it to PNG.
if test "$1" != "$AsPng"; then
while ! test -e $TempDirectory/.ready; do echo "Waiting for netpbm to catch up"; sleep 1; done # (TODO unless on an SMP system. Doing it this way rather than 'wait' for a PID because sometimes Cygwin's wait is broken.)
rm $TempDirectory/.ready
(anytopnm "$1" | pnmtopng -compression 9 > "$AsPng" && rm "$1"; touch $TempDirectory/.ready) &
fi
shift; continue
fi
pushd "$HOME"
for File in .gimp*/tmp/*-area.png; do
export Geom=$(pngtopnm $File | head -2 | tail -1)
if test $(echo $Geom|sed -e 's/ .*//') -gt 300; then break; else unset Geom; fi
done
popd
if [ ! "$Geom" ]; then
echo ; echo "ERROR: You did not select a large enough area for reliable rotation (must be at least 300 pixels wide)."
echo "(This error can also be caused by a timing bug in some versions of the GIMP - try doing it again more slowly.)"
echo "Press Enter to try again."
read
elif test $NumFiles -gt 2; then
echo "ERROR: you need to choose 0, 1 or 2 areas, not $NumFiles"
echo "Press Enter to try again."
read
else
export Deg=$(echo $Geom | python -c 'import sys,math; w,h=sys.stdin.read().split() ; print(math.atan(1.0*int(h)/int(w))*180/math.pi)') # Python 2 and Python 3 should both work
if test $NumFiles == 2; then export Deg=-$Deg; fi
while ! test -e $TempDirectory/.ready; do echo "Waiting for netpbm to catch up"; sleep 1; done; rm $TempDirectory/.ready # as above
# some buggy versions of pnmrotate don't like -background=white on a PPM (2-colour) image, so we need to make sure it's at least greyscale first, ideally in the same pipe. pnmtopng/pngtopnm doesn't always do it. Piping through ppmtopcx/pcxtoppm or pnmtorle/rletopnm seems to work.
# (we also allow for very old versions of pnmrotate that don't have the -background=white switch)
# (and we use 1.0,1.0,1.0 instead of 'white' in case rgb.txt isn't properly present on the system)
(anytopnm "$1" | pnmtorle | rletopnm | (pnmrotate -background=1.0,1.0,1.0 -noantialias $Deg 2>/dev/null || pnmrotate -noantialias $Deg) | pnmtopng -compression 9 > "$1.new" && rm "$1" && mv "$1.new" "$AsPng"; touch $TempDirectory/.ready) &
NeedRemove="$AsPng $NeedRemove" # hope no spaces in there
shift
fi
(cd "$HOME";rm .gimp*/tmp/*-area.png)
done
while ! test -e $TempDirectory/.ready; do echo "Waiting for netpbm to catch up"; sleep 1; done
if [ "$NeedRemove" ]; then clear; fi
echo "All images have been de-rotated."
rm -rf $TempDirectory
if [ ! "$NeedRemove" ]; then exit; fi
echo "One more thing: You may need to manually remove any large
marks at the edges of the scan; these are quite likely if
the document was rotated when the area to scan was selected,
and they can confuse further processing (especially marks to
the left and right of the text). So we will now run gimp
again, on just the files that have been de-rotated last
time. For each one, select any unwanted marks, Cut
(Control-X), Save (Control-S) and Quit (Control-Q). (NB if
you need to select more than one mark then you may need to
click outside each selection before making the next one)"
echo "Press Enter to start."
read
for I in $NeedRemove; do
if test -d /cygdrive; then
# looks like we're on CygWin - this is tricky
cp "$I" /cygdrive/c/Program*Files/GIMP*/bin
pushd /cygdrive/c/Program*Files/GIMP*/bin
./gimp*.exe -d -s "$I"
#echo "Press Enter when Gimp has terminated" ; read
mv "$I" "$OLDPWD"
popd
else gimp -d -s "$I"; fi; done
echo "All done."