diff --git a/bin/medie b/bin/medie new file mode 100755 index 0000000..ba95ce8 --- /dev/null +++ b/bin/medie @@ -0,0 +1,239 @@ +#!/usr/bin/env nuxsh + +nux.use nux/fs + +type ffmpeg > /dev/null 2>&1 && FFMPEG_OR_LIBAV=ffmpeg +type avconv > /dev/null 2>&1 && FFMPEG_OR_LIBAV=avconv +type gm > /dev/null 2>&1 && NUX_MAGICK=gm + +QUALITY=${QUALITY:=95} +DUPLICATE_THRESHOLD=${DUPLICATE_THRESHOLD:=90%} +SKIP_CHECK=no_skip +nux.log debug "FFMPEG: $FFMPEG_OR_LIBAV Magick: $NUX_MAGICK" + +## Performs operations on media such as images or videos. +## Use env **QUALITY** to specify compression quality. +## +## # Available tasks: +@command video.change.container { + CONTAINER=$1; + shift; + echo "Using $FFMPEG_OR_LIBAV for conversion." + for video in "$@"; do + echo "Starting processing Video: $video"; + $FFMPEG_OR_LIBAV -i "$video" -vcodec copy -acodec copy "${video}.$CONTAINER" + echo "Processing done."; + done +} + +@command function :nikon-mp4 { + task.video.change.container mp4 "$@" + } + + +@command keep-path task { + +} + +## remove-orig:: +## Runs specified task, but remove original images if applicable. +## This keyword is applicable for *downscale*, *to* +@command remove-orig task { + nuxr.run "$task" "$@" +} + +## no-overwrite:: +## Runs specified task, but remove original images if applicable. +## This keyword is applicable for *downscale*, *to* +@command no-overwrite task { + SKIP_CHECK=nux.fs.exists + nuxr.run "$task" "$@" +} + +@command preserve task { + PRESERVE=true + nuxr.run "$task" "$@" +} + +## downscale:: +## Creates downscaled copy of image in *target* directory. +## Image is downsampled to fit in *size*. Smaller images are not upscaled. +@command downscale TARGET SIZE { + local i=0; + local count="$#"; + mkdir -p $TARGET; + for image in "$@"; do + let "i=i+1" + name="$(basename "$image")"; + target_file="$TARGET/$name"; + if [ -n "$PRESERVE" ]; then + target_dir="${TARGET}/$(dirname "$image")"; + mkdir -p "$target_dir"; + target_file="${target_dir}/$name"; + fi + if $SKIP_CHECK "$target_file" ; then + echo "Image: $i/$count Skipping" + else + echo "Image: $i/$count Downsampling $image -> '$target_file'" + $NUX_MAGICK convert "$image" \ + -filter Lanczos -sampling-factor 1x1 \ + -resize "${SIZE}x${SIZE}>" \ + -quality $QUALITY \ + "$target_file" + fi + done +} + +## to:: <**jpg|png**> +## Convert image to specified format. +@command to target { + if ! nux.check.function "media.to.$target" ; then + echo Target type "$target" is not supported. + return -1 + fi + for file in "$@"; do + target_dir=$(dirname "$file"); + target_file=$(basename "$file" | sed -re 's/\.[a-z0-9_]+$//g' -e "s/\$/.$target/g" ); + target_full="$target_dir/$target_file"; + media.to.$target "$file" "$target_full" + echo $file $target_file + done +} + +## side-by-side:: +## Joins two images horizontal (assuming they have same size). +### +### Useful for: +### - generating RGBD Images for *holograms* - *left is color* space, *right is depth* +### - joining Instagram photos in slideshow, where photo is splitted in middle +@command side-by-side left right output { + $NUX_MAGICK montage -mode concatenate "$left" "$right" -geometry +0+0 -quality $QUALITY "$output" + nux.fs.info "$output" "Created" +} + +## list-smaller:: +## Lists images smaller than **size**. +@command list-smaller size { + $NUX_MAGICK identify -format "%f;%w;%h\n" "$@" | while IFS=";" read file w h ; do + if [ -z "$file" ]; then + continue; + fi + if [ $w -gt $size ] && [ $h -gt $size ]; then + continue; + fi + echo "$file $w $h" + done +} + +@command list-different size { + $NUX_MAGICK identify -format "%f;%w;%h\n" "$@" | while IFS=";" read file w h ; do + if [ -z "$file" ]; then + continue; + fi + if [ $w -eq $size ] && [ $h -eq $size ]; then + continue; + fi + echo "$file $w $h" + done +} + +## duplicates:: +## Analyse images for duplicates and display duplicate groups using feh. +## When image is displayed following actions are available: +## 0:: Keep file +## 1:: Move to folder with name of first image +## 2:: Replace with symlink to first image +## 3:: Remove file +### +### Environment variables: +### DUPLICATE_THRESHOLD:: Sets similarity treshold when images are +### considered similar. Default value is *90%* +### +@command duplicates { + nux.require findimagedupes + nux.require feh + findimagedupes -t $DUPLICATE_THRESHOLD "$@" | while read duplicate_set; do + largest=$(img.largest $duplicate_set) + set_name=${largest%.*} + nux.fs.info $largest Set name: $set_name + feh_files=""; + for file in $duplicate_set; do + file=$(nux.fs.path.relative.pwd "$file"); + #nux.fs.info $largest Possible duplicate $file + feh_files="$feh_files $file"; + done + feh \ + --zoom max \ + --scale-down \ + -G \ + --action '[keep]echo %F: Keeping file.' \ + --action1 "[move]echo %F: Moving to $set_name ; mkdir -p $set_name ; mv -t $set_name %F ;" \ + --action2 "[symlink]echo %F: Replacing with symlink to $largest ; ln -sf $largest %F ;" \ + --action3 "[delete] echo %F Removing file; rm -f %F;" \ + --info 'echo %n: %wx%h' \ + --draw-tinted $feh_files + done +} + +## feh:: +## Displays images using feh. +## When image is displayed following actions are available: +## 0:: Next file +## 1:: - +## 2:: - +## 3:: Remove file +@command feh { + feh \ + --zoom max \ + --scale-down \ + -G \ + --action '[keep]echo %F: Keeping file.' \ + --action3 "[delete] echo %F Removing file; rm -f %F;" \ + --info 'echo %n: %wx%h' \ + --draw-tinted "$@" +} + +function img.largest { + ## FIXME: Identify largest image + nux.fs.path.relative.pwd "$1"; +} + +function media.to.jpg { + $NUX_MAGICK convert "$1" -quality $QUALITY -auto-orient "$2" +} + +function media.to.png { + $NUX_MAGICK convert "$1" -quality $QUALITY -auto-orient "$2" +} + +function no_skip { + return 1; +} + + +@command mass-crop label target { + for img in "$@"; do + without_suffix=${img%.*}; + suffix=${img##*.}; + id=${without_suffix##*/} + nux.log debug "Image: $img ID: $id" + img_size=$($NUX_MAGICK identify "$img" -format "%h %w" ) + img_h=${img_size%% *}; + img_w=${img_size##* }; + i=1; + if [ -e "$ANNOTATIONS/${id}.bboxes" ]; then + grep "^$label" "$ANNOTATIONS/${id}.bboxes" | while read label cx cy w h; do + w=$(nux.round $(nux.calc "$w*$img_w") 0); + h=$(nux.round $(nux.calc "$h*$img_h") 0); + x=$(nux.round $(nux.calc "$cx*$img_w-$w*0.5") 0); + y=$(nux.round $(nux.calc "$cy*$img_h-$h*0.5") 0); + nux.fs.info "$img" "cropping ${w}x${h}+${x}+${y} to " "$target/$id.$i.$suffix" + $NUX_MAGICK convert "$img" -crop "${w}x${h}+${x}+${y}" "$target/$id.$i.$suffix" + let "i=i+1" + done; + fi + done; + + + +} diff --git a/bin/tdm-media b/bin/tdm-media deleted file mode 100755 index 5614011..0000000 --- a/bin/tdm-media +++ /dev/null @@ -1,229 +0,0 @@ -#!/usr/bin/env nuxsh - -nux.use nux/fs - -type ffmpeg > /dev/null 2>&1 && FFMPEG_OR_LIBAV=ffmpeg -type avconv > /dev/null 2>&1 && FFMPEG_OR_LIBAV=avconv -type gm > /dev/null 2>&1 && NUX_MAGICK=gm - -QUALITY=${QUALITY:=95} -DUPLICATE_THRESHOLD=${DUPLICATE_THRESHOLD:=90%} -SKIP_CHECK=no_skip -nux.log debug "FFMPEG: $FFMPEG_OR_LIBAV Magick: $NUX_MAGICK" - -## Performs operations on media such as images or videos. -## Use env **QUALITY** to specify compression quality. -## -## # Available tasks: -@command video.change.container { - CONTAINER=$1; - shift; - echo "Using $FFMPEG_OR_LIBAV for conversion." - for video in "$@"; do - echo "Starting processing Video: $video"; - $FFMPEG_OR_LIBAV -i "$video" -vcodec copy -acodec copy "${video}.$CONTAINER" - echo "Processing done."; - done -} - -@command function :nikon-mp4 { - task.video.change.container mp4 "$@" - } - - -@command keep-path task { - -} - -## remove-orig:: -## Runs specified task, but remove original images if applicable. -## This keyword is applicable for *downscale*, *to* -@command remove-orig task { - nuxr.run "$task" "$@" -} - -## no-overwrite:: -## Runs specified task, but remove original images if applicable. -## This keyword is applicable for *downscale*, *to* -@command no-overwrite task { - SKIP_CHECK=nux.fs.exists - nuxr.run "$task" "$@" -} - -@command preserve task { - PRESERVE=true - nuxr.run "$task" "$@" -} - -## downscale:: -## Creates downscaled copy of image in *target* directory. -## Image is downsampled to fit in *size*. Smaller images are not upscaled. -@command downscale TARGET SIZE { - local i=0; - local count="$#"; - mkdir -p $TARGET; - for image in "$@"; do - let "i=i+1" - name="$(basename "$image")"; - target_file="$TARGET/$name"; - if [ -n "$PRESERVE" ]; then - target_dir="${TARGET}/$(dirname "$image")"; - mkdir -p "$target_dir"; - target_file="${target_dir}/$name"; - fi - if $SKIP_CHECK "$target_file" ; then - echo "Image: $i/$count Skipping" - else - echo "Image: $i/$count Downsampling $image -> '$target_file'" - $NUX_MAGICK convert "$image" \ - -filter Lanczos -sampling-factor 1x1 \ - -resize "${SIZE}x${SIZE}>" \ - -quality $QUALITY \ - "$target_file" - fi - done - } - - -## to:: <**jpg|png**> -## Convert image to specified format. -@command to target { - if ! nux.check.function "media.to.$target" ; then - echo Target type "$target" is not supported. - return -1 - fi - for file in "$@"; do - target_dir=$(dirname "$file"); - target_file=$(basename "$file" | sed -re 's/\.[a-z0-9_]+$//g' -e "s/\$/.$target/g" ); - target_full="$target_dir/$target_file"; - media.to.$target "$file" "$target_full" - echo $file $target_file - done - } - -## list-smaller:: -## Lists images smaller than **size**. -@command list-smaller size { - $NUX_MAGICK identify -format "%f;%w;%h\n" "$@" | while IFS=";" read file w h ; do - if [ -z "$file" ]; then - continue; - fi - if [ $w -gt $size ] && [ $h -gt $size ]; then - continue; - fi - echo "$file $w $h" - done -} - -@command list-different size { - $NUX_MAGICK identify -format "%f;%w;%h\n" "$@" | while IFS=";" read file w h ; do - if [ -z "$file" ]; then - continue; - fi - if [ $w -eq $size ] && [ $h -eq $size ]; then - continue; - fi - echo "$file $w $h" - done -} - -## duplicates:: -## Analyse images for duplicates and display duplicate groups using feh. -## When image is displayed following actions are available: -## 0:: Keep file -## 1:: Move to folder with name of first image -## 2:: Replace with symlink to first image -## 3:: Remove file -### -### Environment variables: -### DUPLICATE_THRESHOLD:: Sets similarity treshold when images are -### considered similar. Default value is *90%* -### -@command duplicates { - nux.require findimagedupes - nux.require feh - findimagedupes -t $DUPLICATE_THRESHOLD "$@" | while read duplicate_set; do - largest=$(img.largest $duplicate_set) - set_name=${largest%.*} - nux.fs.info $largest Set name: $set_name - feh_files=""; - for file in $duplicate_set; do - file=$(nux.fs.path.relative.pwd "$file"); - #nux.fs.info $largest Possible duplicate $file - feh_files="$feh_files $file"; - done - feh \ - --zoom max \ - --scale-down \ - -G \ - --action '[keep]echo %F: Keeping file.' \ - --action1 "[move]echo %F: Moving to $set_name ; mkdir -p $set_name ; mv -t $set_name %F ;" \ - --action2 "[symlink]echo %F: Replacing with symlink to $largest ; ln -sf $largest %F ;" \ - --action3 "[delete] echo %F Removing file; rm -f %F;" \ - --info 'echo %n: %wx%h' \ - --draw-tinted $feh_files - done -} - -## feh:: -## Displays images using feh. -## When image is displayed following actions are available: -## 0:: Next file -## 1:: - -## 2:: - -## 3:: Remove file -@command feh { - feh \ - --zoom max \ - --scale-down \ - -G \ - --action '[keep]echo %F: Keeping file.' \ - --action3 "[delete] echo %F Removing file; rm -f %F;" \ - --info 'echo %n: %wx%h' \ - --draw-tinted "$@" -} - -function img.largest { - ## FIXME: Identify largest image - nux.fs.path.relative.pwd "$1"; -} - -function media.to.jpg { - $NUX_MAGICK convert "$1" -quality $QUALITY -auto-orient "$2" -} - -function media.to.png { - $NUX_MAGICK convert "$1" -quality $QUALITY -auto-orient "$2" -} - -function no_skip { - return 1; -} - - -@command mass-crop label target { - for img in "$@"; do - without_suffix=${img%.*}; - suffix=${img##*.}; - id=${without_suffix##*/} - nux.log debug "Image: $img ID: $id" - img_size=$($NUX_MAGICK identify "$img" -format "%h %w" ) - img_h=${img_size%% *}; - img_w=${img_size##* }; - i=1; - if [ -e "$ANNOTATIONS/${id}.bboxes" ]; then - grep "^$label" "$ANNOTATIONS/${id}.bboxes" | while read label cx cy w h; do - w=$(nux.round $(nux.calc "$w*$img_w") 0); - h=$(nux.round $(nux.calc "$h*$img_h") 0); - x=$(nux.round $(nux.calc "$cx*$img_w-$w*0.5") 0); - y=$(nux.round $(nux.calc "$cy*$img_h-$h*0.5") 0); - nux.fs.info "$img" "cropping ${w}x${h}+${x}+${y} to " "$target/$id.$i.$suffix" - $NUX_MAGICK convert "$img" -crop "${w}x${h}+${x}+${y}" "$target/$id.$i.$suffix" - let "i=i+1" - done; - fi - done; - - - -} diff --git a/bin/tdm-media b/bin/tdm-media new file mode 120000 index 0000000..edf88b8 --- /dev/null +++ b/bin/tdm-media @@ -0,0 +1 @@ +medie \ No newline at end of file diff --git a/bin/tdm-media-cbz b/bin/tdm-media-cbz deleted file mode 100755 index 027ac42..0000000 --- a/bin/tdm-media-cbz +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh - -## -## Creates cbz archive from supplied folder. -## - -FILENAME=$(basename $0) -show_help() { - echo $FILENAME - grep "\#\#" $0 | cut -d\# -f3- - echo -} - -PREFIX=""; -DELETE_AFTER=false -SUFFIX=cbz -while getopts "hp:s:d" opt; do - case $opt in - -## -## -p Prefix resulting filenames with supplied prefix. -## -## All resulting files will start with supplied -## prefix e.g. -p foo- bar baz will result in -## creation of archives foo-bar.cbz and foo-baz.cbz: -## - p) - PREFIX="$OPTARG"; - ;; - -## -## -d Delete supplied folders after creating archives. - d) - DELETE_AFTER=true; - ;; -## -## -s Change file type suffix from default cbz to specified. -## -## All resulting files will end with supplied suffix instead -## of cbz. E.g. -s zip will trigger creation of normal zip files. - s) - SUFFIX="$OPTARG"; - ;; - h) - show_help;exit 1;; - \?) show_help;exit 1;; - :) echo "Option -$OPTARG requires an argument." >&2 ; exit 1;; - esac -done - -shift $(($OPTIND-1)) - -echo Prefix: $PREFIX Suffix: Delete folders: $DELETE_AFTER -echo $@ -for DIR in "$@"; do - if [ -d "$DIR" ]; then - NAME=$(basename "$DIR") - echo "Going to create $NAME" - zip -r "${PREFIX}${NAME}.${SUFFIX}" "$DIR" - fi -done - diff --git a/bin/tdm-media-nikon-mov-keyframes-jpeg b/bin/tdm-media-nikon-mov-keyframes-jpeg deleted file mode 100755 index 466fcc1..0000000 --- a/bin/tdm-media-nikon-mov-keyframes-jpeg +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -## Extract keyframes from Nikon J1 MOV files -ffmpeg -i *.MOV -vf "select=eq(pict_type\,I),setpts=N/(29.97*TB)" thumbnails-%02d.jpeg \ No newline at end of file