Skip to content
Snippets Groups Projects
Commit 805d3a84 authored by Toke Eskildsen's avatar Toke Eskildsen
Browse files

Merge branch 'master' of github.com:tokee/quack

parents f94efcde f44f5658
No related branches found
No related tags found
No related merge requests found
...@@ -6,8 +6,11 @@ ...@@ -6,8 +6,11 @@
# Requirements: ImageMagick's identify and convert # Requirements: ImageMagick's identify and convert
# #
# TODO: Move this outside of the script # If true, input files are assumed to be greyscale.
ASSUME_GREY=true # If false, they are converted to greyscale before extracting statistics.
if [ "." == ".$ASSUME_GREY" ]; then
ASSUME_GREY=true
fi
# TODO: Accept destination for identify-file as input # TODO: Accept destination for identify-file as input
......
...@@ -59,5 +59,6 @@ if [ "." == ".$DESTINATION" ]; then ...@@ -59,5 +59,6 @@ if [ "." == ".$DESTINATION" ]; then
exit 2 exit 2
fi fi
get_commands "$SOURCE" get_commands "$SOURCE"
gm convert "$SOURCE" $COMMANDS "$DESTINATION" gm convert "$SOURCE" $COMMANDS "$DESTINATION"
...@@ -126,6 +126,9 @@ TILE="false" ...@@ -126,6 +126,9 @@ TILE="false"
# The view represents an end-user version of the scan. This will often be # The view represents an end-user version of the scan. This will often be
# downscaled, levelled, sharpened and JPEG'ed. # downscaled, levelled, sharpened and JPEG'ed.
export PRESENTATION="true" export PRESENTATION="true"
# The image format for the presentation image. Possible values are png and jpg.
# jpg is recommended as this would normally be the choice for end-user presentation.
export PRESENTATION_IMAGE_DISP_EXT="jpg"
# Overlay colors for indicating burned out high- and low-lights # Overlay colors for indicating burned out high- and low-lights
export OVERLAY_BLACK=3399FF export OVERLAY_BLACK=3399FF
...@@ -133,13 +136,28 @@ export OVERLAY_WHITE=FFFF00 ...@@ -133,13 +136,28 @@ export OVERLAY_WHITE=FFFF00
# Snippets are inserted verbatim at the top of the folder and the image pages. # Snippets are inserted verbatim at the top of the folder and the image pages.
# Use them for specifying things like delivery date or provider notes. # Use them for specifying things like delivery date or provider notes.
# Note that these snippet can be overridden on a per-folder and per-image basis
# by creating special files in the source tree (see SPECIFIC_FOLDER_SNIPPET and
# SPECIFIC_IMAGE_SNIPPET_EXTENSION below).
export SNIPPET_FOLDER="" export SNIPPET_FOLDER=""
export SNIPPET_IMAGE="" export SNIPPET_IMAGE=""
# End default settings. User-supplied overrides will be loaded from quack.settings # End default settings. User-supplied overrides will be loaded from quack.settings
# If present in a source-folder, the content of the folder will be inserted into
# the generated folder HTML file.
SPECIFIC_FOLDER_SNIPPET="folder.snippet"
# If a file with image basename + this extension is encountered, the content will
# be inserted into the generated image HTML file.
SPECIFIC_IMAGE_SNIPPET_EXTENSION=".snippet"
# If no OpenSeadragon is present, the scripts attempts to download this version.
OSD_ZIP="openseadragon-bin-1.0.0.zip"
OSD_DIRECT="http://github.com/openseadragon/openseadragon/releases/download/v1.0.0/$OSD_ZIP"
START_PATH=`pwd`
pushd `dirname $0` > /dev/null pushd `dirname $0` > /dev/null
ROOT=`pwd` ROOT=`pwd`
if [ -e "quack.settings" ]; then if [ -e "quack.settings" ]; then
...@@ -151,25 +169,29 @@ source "analyze.sh" ...@@ -151,25 +169,29 @@ source "analyze.sh"
popd > /dev/null popd > /dev/null
# Local settings overrides general settings # Local settings overrides general settings
if [ -e "quack.settings" ]; then if [ ! "$START_PATH" == "$ROOT" ]; then
echo "Sourcing user settings from quack.settings in `pwd`" if [ -e "quack.settings" ]; then
source "quack.settings" echo "Sourcing user settings from quack.settings in `pwd`"
source "quack.settings"
fi
fi fi
if [ ".true" == ".$FORCE_BLOWN" ]; then if [ ".true" == ".$FORCE_BLOWN" ]; then
# When we force regeneration of blown, we myst also regenerate the blown thumbs. # When we force regeneration of blown, we myst also regenerate the blown thumbs.
export FORCE_BLOWN_THUMBS=true export FORCE_BLOWN_THUMBS=true
fi fi
PRESENTATION_SCRIPT="$ROOT/presentation.sh" PRESENTATION_SCRIPT="$ROOT/presentation.sh"
FOLDER_TEMPLATE="$ROOT/folder_template.html" if [ -f "$START_PATH/presentation.sh" ]; then
IMAGE_TEMPLATE="$ROOT/image_template.html" echo "Using presentation.sh located in $START_PATH"
PRESENTATION_SCRIPT="$START_PATH/presentation.sh"
fi
FOLDER_TEMPLATE="$ROOT/web/folder_template.html"
IMAGE_TEMPLATE="$ROOT/web/image_template.html"
DRAGON="openseadragon.min.js" DRAGON="openseadragon.min.js"
function usage() { function usage() {
echo "quack 1.1 beta - Quality Assurance oriented ALTO viewer" echo "quack 1.2 beta - Quality Assurance oriented ALTO viewer"
echo "" echo ""
echo "Usage: ./quack.sh source destination" echo "Usage: ./quack.sh source destination"
echo "" echo ""
...@@ -197,10 +219,37 @@ if [ "." == ".$DEST" ]; then ...@@ -197,10 +219,37 @@ if [ "." == ".$DEST" ]; then
usage usage
exit 2 exit 2
fi fi
if [ ! -f "$ROOT/$DRAGON" ]; then if [ ! -f "$ROOT/web/$DRAGON" ]; then
echo "The file $ROOT/$DRAGON does not exist" >&2 if [ -f "$ROOT/$DRAGON" ]; then
echo "Please download it at http://openseadragon.github.io/#download" >&2 echo "Copying $DRAGON from Quack root to the web folder"
exit cp "$ROOT/$DRAGON" "$ROOT/web/"
else
echo "The file $ROOT/$DRAGON or $ROOT/web/$DRAGON does not exist" >&2
if [ "." == ".`which wget`" -o "." == ".`which unzip`" ]; then
echo "Please download it at http://openseadragon.github.io/#download" >&2
echo "Tested version is 1.0.0, which can be downloaded from" >&2
echo "$OSD_DIRECT" >&2
exit
else
echo "Attempting to download of OpenSeadragon from" >&2
echo "$OSD_DIRECT"
wget "$OSD_DIRECT" -O "$ROOT/web/$OSD_ZIP"
pushd "$ROOT/web" > /dev/null
unzip "$ROOT/web/$OSD_ZIP" "openseadragon-bin-1.0.0/openseadragon.min.js"
mv "openseadragon-bin-1.0.0/openseadragon.min.js" "$DRAGON"
rm -r "openseadragon-bin-1.0.0"
popd > /dev/null
rm "$ROOT/web/$OSD_ZIP"
if [ ! -f "$ROOT/web/$DRAGON" ]; then
echo "Automatic OpenSeadragon download and installation failed." >&2
echo "Please download it at http://openseadragon.github.io/#download" >&2
echo "Tested version is 1.0.0, which can be downloaded from" >&2
echo "$OSD_DIRECT" >&2
exit 2
fi
echo "Automatic download and installation of OpenSeadragon successful."
fi
fi
fi fi
# Copy OpenSeadragon and all css-files to destination # Copy OpenSeadragon and all css-files to destination
...@@ -209,9 +258,8 @@ function copyFiles () { ...@@ -209,9 +258,8 @@ function copyFiles () {
echo "Creating folder $DEST" echo "Creating folder $DEST"
mkdir -p "$DEST" mkdir -p "$DEST"
fi fi
cp "${ROOT}/${DRAGON}" "$DEST" cp ${ROOT}/web/*.js "$DEST"
cp ${ROOT}/*.js "$DEST" cp ${ROOT}/web/*.css "$DEST"
cp ${ROOT}/*.css "$DEST"
} }
# http://stackoverflow.com/questions/14434549/how-to-expand-shell-variables-in-a-text-file # http://stackoverflow.com/questions/14434549/how-to-expand-shell-variables-in-a-text-file
...@@ -254,9 +302,9 @@ function template () { ...@@ -254,9 +302,9 @@ function template () {
# srcFolder dstFolder image # srcFolder dstFolder image
# Output: SOURCE_IMAGE DEST_IMAGE HIST_IMAGE THUMB # Output: SOURCE_IMAGE DEST_IMAGE HIST_IMAGE THUMB
function makeImageParams() { function makeImageParams() {
local SRC_FOLDER=$1 local SRC_FOLDER="$1"
local DEST_FOLDER=$2 local DEST_FOLDER="$2"
local IMAGE=$3 local IMAGE="$3"
local SANS_PATH=${IMAGE##*/} local SANS_PATH=${IMAGE##*/}
local BASE=${SANS_PATH%.*} local BASE=${SANS_PATH%.*}
...@@ -272,6 +320,8 @@ function makeImageParams() { ...@@ -272,6 +320,8 @@ function makeImageParams() {
BLACK_IMAGE="${DEST_FOLDER}/${BASE}.black.png" BLACK_IMAGE="${DEST_FOLDER}/${BASE}.black.png"
PRESENTATION_IMAGE="${DEST_FOLDER}/${BASE}.presentation.jpg" PRESENTATION_IMAGE="${DEST_FOLDER}/${BASE}.presentation.jpg"
TILE_FOLDER="${DEST_FOLDER}/${BASE}_files" TILE_FOLDER="${DEST_FOLDER}/${BASE}_files"
PRESENTATION_TILE_FOLDER="${DEST_FOLDER}/${BASE}.presentation_files"
ALTO_DEST="${DEST_FOLDER}/${BASE}.alto.xml"
} }
# If force is true and image exists, image is deleted and true returned # If force is true and image exists, image is deleted and true returned
...@@ -324,6 +374,8 @@ function makeImages() { ...@@ -324,6 +374,8 @@ function makeImages() {
local THUMB_OVERLAY_BLACK="${DEST_FOLDER}/${BASE}.black.thumb.png" local THUMB_OVERLAY_BLACK="${DEST_FOLDER}/${BASE}.black.thumb.png"
local PRESENTATION_IMAGE="${DEST_FOLDER}/${BASE}.presentation.jpg" local PRESENTATION_IMAGE="${DEST_FOLDER}/${BASE}.presentation.jpg"
local TILE_FOLDER="${DEST_FOLDER}/${BASE}_files" local TILE_FOLDER="${DEST_FOLDER}/${BASE}_files"
local PRESENTATION_TILE_FOLDER="${DEST_FOLDER}/${BASE}.presentation_files"
local ALTO_DEST="${DEST_FOLDER}/${BASE}.alto.xml"
if [ ! -f "$SOURCE_IMAGE" ]; then if [ ! -f "$SOURCE_IMAGE" ]; then
echo "The source image $S does not exists" >&2 echo "The source image $S does not exists" >&2
...@@ -348,6 +400,10 @@ function makeImages() { ...@@ -348,6 +400,10 @@ function makeImages() {
# TODO: Specify JPEG quality # TODO: Specify JPEG quality
deepzoom "$CONV" -format $IMAGE_DISP_EXT -path "${DEST_FOLDER}/" deepzoom "$CONV" -format $IMAGE_DISP_EXT -path "${DEST_FOLDER}/"
fi fi
if shouldGenerate "$FORCE_TILES" "$PRESENTATION_TILE_FOLDER" "tiles"; then
# TODO: Specify JPEG quality
deepzoom "$PRESENTATION_IMAGE" -format $PRESENTATION_IMAGE_DISP_EXT -path "${DEST_FOLDER}/"
fi
fi fi
if shouldGenerate "$FORCE_BLOWN" "$WHITE_IMAGE" "overlay"; then if shouldGenerate "$FORCE_BLOWN" "$WHITE_IMAGE" "overlay"; then
...@@ -505,14 +561,16 @@ function processALTO() { ...@@ -505,14 +561,16 @@ function processALTO() {
OVERLAYS="${OVERLAYS}]" OVERLAYS="${OVERLAYS}]"
return return
fi fi
cp "$ALTO" "$DEST"
cp "$ALTO" "$ALTO_DEST"
# Extract key elements from the ALTO # Extract key elements from the ALTO
local ALTO_COMPACT=`cat "$ALTO_FILE" | sed ':a;N;$!ba;s/\\n/ /g'` local ALTO_COMPACT=`cat "$ALTO_FILE" | sed ':a;N;$!ba;s/\\n/ /g'`
# local PTAG=`echo "$ALTO_COMPACT" | grep -o "<PrintSpace[^>]\\+>"` # local PTAG=`echo "$ALTO_COMPACT" | grep -o "<PrintSpace[^>]\\+>"`
local PTAG=`echo "$ALTO_COMPACT" | grep -o "<Page[^>]\\+>"` local PTAG=`echo "$ALTO_COMPACT" | grep -o "<Page[^>]\\+>"`
local PHEIGHT=`echo $PTAG | sed 's/.*HEIGHT=\"\([^"]\+\)".*/\\1/g'` local PHEIGHT=`echo $PTAG | sed 's/.*HEIGHT=\"\([^"]\+\)".*/\\1/g'`
local PWIDTH=`echo $PTAG | sed 's/.*WIDTH=\"\([^"]\+\)".*/\\1/g'` local PWIDTH=`echo $PTAG | sed 's/.*WIDTH=\"\([^"]\+\)".*/\\1/g'`
ACCURACY=`echo $PTAG | sed 's/.*ACCURACY=\"\([^"]\+\)".*/\\1/g'` ACCURACY=`echo $PTAG | sed 's/.*PC=\"\([^"]\+\)".*/\\1/g'`
ACCURACY=`echo "scale=2;$ACCURACY*100" | bc`
FULL_RELATIVE_HEIGHT=`echo "scale=6;$PHEIGHT/$PWIDTH" | bc | sed 's/^\./0./'` FULL_RELATIVE_HEIGHT=`echo "scale=6;$PHEIGHT/$PWIDTH" | bc | sed 's/^\./0./'`
# TODO: Ponder how relative positioning works and why this hack is necessary # TODO: Ponder how relative positioning works and why this hack is necessary
...@@ -590,6 +648,14 @@ function makePreviewPage() { ...@@ -590,6 +648,14 @@ function makePreviewPage() {
BASE=${SANS_PATH%.*} BASE=${SANS_PATH%.*}
P="${DEST_FOLDER}/${BASE}.html" P="${DEST_FOLDER}/${BASE}.html"
local SSNIP="${BASE}${SPECIFIC_IMAGE_SNIPPET_EXTENSION}"
if [ -f $SSNIP ]; then
SNIPPET=`cat $SSNIP`
else
SNIPPET="$SNIPPET_FOLDER"
fi
# Used by function caller # Used by function caller
PAGE_LINK="${BASE}.html" PAGE_LINK="${BASE}.html"
...@@ -661,6 +727,21 @@ function makePreviewPage() { ...@@ -661,6 +727,21 @@ function makePreviewPage() {
Height: \"$IMAGE_HEIGHT\"\ Height: \"$IMAGE_HEIGHT\"\
}\ }\
}"$'\n' }"$'\n'
if [ ".true" == ".$PRESENTATION" ]; then
PRESENTATION_TILE_SOURCES=" Image: {\
xmlns: \"http://schemas.microsoft.com/deepzoom/2008\",\
Url: \"${PRESENTATION_TILE_FOLDER##*/}/\",\
Format: \"$PRESENTATION_IMAGE_DISP_EXT\",\
Overlap: \"4\",\
TileSize: \"256\",\
Size: {\
Width: \"$PRESENTATION_WIDTH\",\
Height: \"$PRESENTATION_HEIGHT\"\
}\
}"$'\n'
else
PRESENTATION_TILE_SOURCES=""
fi
else else
TILE_SOURCES=" type: 'legacy-image-pyramid',\ TILE_SOURCES=" type: 'legacy-image-pyramid',\
levels:[\ levels:[\
...@@ -670,15 +751,20 @@ function makePreviewPage() { ...@@ -670,15 +751,20 @@ function makePreviewPage() {
height: ${IMAGE_HEIGHT}\ height: ${IMAGE_HEIGHT}\
}\ }\
]"$'\n' ]"$'\n'
if [ ".true" == ".$PRESENTATION" ]; then
PRESENTATION_TILE_SOURCES=" type: 'legacy-image-pyramid',\
levels:[\
{\
url: '${PRESENTATION_IMAGE##*/}',\
width: ${PRESENTATION_WIDTH},\
height: ${PRESENTATION_HEIGHT}\
}\
]"$'\n'
else
PRESENTATION_TILE_SOURCES=""
fi
fi fi
THUMB="$THUMB_LINK" THUMB="$THUMB_LINK"
if [ ".true" == ".$PRESENTATION" ]; then
PRESENTATION_LINK=${PRESENTATION_IMAGE##*/}
else
PRESENTATION_LINK=""
PRESENTATION_WIDTH=0
PRESENTATION_HEIGHT=0
fi
WHITE_LINK=${WHITE_IMAGE##*/} WHITE_LINK=${WHITE_IMAGE##*/}
WHITE="$WHITE_LINK" WHITE="$WHITE_LINK"
BLACK_LINK=${BLACK_IMAGE##*/} BLACK_LINK=${BLACK_IMAGE##*/}
...@@ -820,7 +906,15 @@ function makeIndex() { ...@@ -820,7 +906,15 @@ function makeIndex() {
done done
fi fi
# UP, PARENT, SRC_FOLDER, DEST_FOLDER, IMAGES_HTML, THUMBS_HTML, SUBFOLDERS_HTML, EDITION_HTML pushd $SRC_FOLDER > /dev/null
if [ -f $SPECIFIC_FOLDER_SNIPPET ]; then
SNIPPET=`cat $SPECIFIC_FOLDER_SNIPPET`
else
SNIPPET="$SNIPPET_FOLDER"
fi
popd > /dev/null
# UP, PARENT, SRC_FOLDER, DEST_FOLDER, IMAGES_HTML, THUMBS_HTML, SUBFOLDERS_HTML, EDITION_HTML, SNIPPET
ctemplate $FOLDER_TEMPLATE > $PP ctemplate $FOLDER_TEMPLATE > $PP
# Generate pages for sub folders # Generate pages for sub folders
......
<p>Frontpage for the newspaper</p>
<p>Sample images from a 200+ year old Danish newspaper</p>
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<body class="folder"> <body class="folder">
<h1>Quack <span style="color: #999">${SRC_FOLDER}</span></h1> <h1>Quack <span style="color: #999">${SRC_FOLDER}</span></h1>
<div class="foldersnippet">${SNIPPET_FOLDER}</div> <div class="foldersnippet">${SNIPPET}</div>
<!-- TODO: Create decent bread crumbs --> <!-- TODO: Create decent bread crumbs -->
<p>Parent folder: <a href="../index.html">${PARENT}</a></p> <p>Parent folder: <a href="../index.html">${PARENT}</a></p>
...@@ -34,5 +34,7 @@ ${SUBFOLDERS_HTML} ...@@ -34,5 +34,7 @@ ${SUBFOLDERS_HTML}
${EDITION_HTML} ${EDITION_HTML}
</div> </div>
<p>Generated `date +"%Y-%m-%d %H:%M"`</p>
</body> </body>
</html> </html>
...@@ -19,7 +19,7 @@ ${IDPREVS} ...@@ -19,7 +19,7 @@ ${IDPREVS}
<body class="previewpage"> <body class="previewpage">
<h1>Quack <span style="color: #999">${SOURCE_SHORT}</span></h1> <h1>Quack <span style="color: #999">${SOURCE_SHORT}</span></h1>
<div class="imagesnippet">${SNIPPET_IMAGE}</div> <div class="imagesnippet">${SNIPPET}</div>
<div id="controlpanel" class="control"> <div id="controlpanel" class="control">
<p class="navigation">${NAVIGATION}</p> <p class="navigation">${NAVIGATION}</p>
...@@ -30,7 +30,7 @@ Darkest ${GREY_FIRST}: ${GREY_PERCENT_FIRST}%<br/> ...@@ -30,7 +30,7 @@ Darkest ${GREY_FIRST}: ${GREY_PERCENT_FIRST}%<br/>
Spike ${GREY_SPIKE}: ${GREY_PERCENT_SPIKE}%<br/> Spike ${GREY_SPIKE}: ${GREY_PERCENT_SPIKE}%<br/>
Lightest ${GREY_LAST}: ${GREY_PERCENT_LAST}%<br/> Lightest ${GREY_LAST}: ${GREY_PERCENT_LAST}%<br/>
Unique greyscale values: ${GREY_UNIQUE}<br/> Unique greyscale values: ${GREY_UNIQUE}<br/>
ALTO-accuracy: ${ACCURACY}% ALTO-PC: ${ACCURACY}%
<p><input type="checkbox" id="toggle_grid" onClick="toggleGrid();">Grid</input></p> <p><input type="checkbox" id="toggle_grid" onClick="toggleGrid();">Grid</input></p>
<p><input type="checkbox" id="toggle_textblock" checked="checked" onClick="toggleTextBlock();">TextBlocks</input></p> <p><input type="checkbox" id="toggle_textblock" checked="checked" onClick="toggleTextBlock();">TextBlocks</input></p>
<p><input type="checkbox" id="toggle_blown" onClick="toggleBlown();">Black/white</input></p> <p><input type="checkbox" id="toggle_blown" onClick="toggleBlown();">Black/white</input></p>
...@@ -119,19 +119,12 @@ ${ALTO_ELEMENTS_HTML} ...@@ -119,19 +119,12 @@ ${ALTO_ELEMENTS_HTML}
<script type="text/javascript"> <script type="text/javascript">
presentationDragon = OpenSeadragon({ presentationDragon = OpenSeadragon({
id: "presentation-display", id: "presentation-display",
maxZoomLevel: 2, maxZoomLevel: 4,
showNavigator: false, showNavigator: false,
wrapHorizontal: false, wrapHorizontal: false,
tileSources: { tileSources: {
type: 'legacy-image-pyramid', ${PRESENTATION_TILE_SOURCES}
levels:[
{
url: '${PRESENTATION_LINK}',
width: ${PRESENTATION_WIDTH},
height: ${PRESENTATION_HEIGHT}
},
]
}}); }});
</script> </script>
...@@ -140,5 +133,7 @@ ${ALTO_ELEMENTS_HTML} ...@@ -140,5 +133,7 @@ ${ALTO_ELEMENTS_HTML}
${GREY_ALL} ${GREY_ALL}
</pre> </pre>
<p>Generated `date +"%Y-%m-%d %H:%M"`</p>
</body> </body>
</html> </html>
/* Basics */
body {
color: #000;
background: none #F5DEB3;
font-family: verdana, sans-serif;
}
h1, h2, h3, h4, h5, h6 { margin-bottom: 0.2em; }
h1 { color: #32611F }
h2, h3, h4, h5, h6 { color: #1F3D14; }
p { margin-top: 0px; }
ul { margin-top: 0px; }
code { color: #900; }
q { font-style: italic; }
a:link { color: #33f; }
a:visited { color: #808; }
a:active { color: #f00; }
/* Signature */
.signature {
font-size: smaller;
text-align: right;
clear: both;
}
p.signature a { font-size: smaller ; }
.signature img { float: right; border: none; }
/* Blocks */
blockquote {
font-style: italic;
border-style: solid;
border-width: 1px;
border-color: #630;
color: #000;
background: none #ff9;
padding: 2px 5px 2px 4px;
}
blockquote em { font-style: normal; }
pre {
background: none #ffc;
border-style: solid;
border-width: 1px;
white-space: pre;
color: #900;
border-color: #000;
padding: 2px 5px 2px 4px;
}
/* Quack specific */
.xmlvalue { .xmlvalue {
color: #066; color: #066;
} }
......
File moved
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment