ImageMagick is failing to identify (or convert) any .eps files, with a no decode delegate error. Below is the full error. Note that running ps2pdf wrapper for Ghostscript does successfully convert the sample EPS file to PDF, but... I guess since ImageMagick can't identify the format, that probably doesn't matter.
identify: no decode delegate for this image format "/my_sample.eps" # error/constitute.c/ReadImage/552.
System info:
ImageMagick 6.8.7-0 2013-10-28 Q16
Mac OS X 10.9 (13A603)
identify -list format | grep EPS returns:
EPS PS rw- Encapsulated PostScript
EPS2* PS2 -w- Level II Encapsulated PostScript
EPS3* PS3 -w+ Level III Encapsulated PostScript
EPSF PS rw- Encapsulated PostScript
EPSI PS rw- Encapsulated PostScript Interchange format
What do
convert -list configure | grep -i delegate
convert -list delegate
return? The following file(s) contain(s) the definitions for all your local delegates' setup:
ls -l $(convert -list delegate | grep Path: | sed 's#Path: ##')
So what does
grep sDEVICE $(convert -list delegate | grep Path: | sed 's#Path: ##')
return?
It may be the case that your EPS file is tainted with some "foreign" data such as PJL commands which are prefixed to the official %!PS...-header lines. This may make the auto-identification of the file impossible. Did you check this?
Related
I want to store an .ogg file inside of a bash script and play it later on in the script. I have tried:
Archiving the .ogg into a .7z file (saves some space), encoding the .7z archive into base64, storing that base64 into my script, and decoding->unzipping->playing the raw .ogg stream.
Encoding the .ogg into base64, storing that base64 into my script, and decoding->playing the raw ogg stream.
Creating a hex dump of the .ogg file, storing that hex into my script, using sed to place \x before every two characters of the hex, using printf to print the hex and <<< it into ogg123 (my ogg player)
Archiving the .ogg into a .7z file (saves some space), creating a hex dump of the .7z file, storing that hex into my script, using sed to place \x before every two characters of the hex, using printf to print the hex, pipe the output into 7za e -si and <<< it into ogg123 (my ogg player)
None of these work. The most successful approach I have had is:
ogg123 <<< cat sound.ogg
However I would really prefer to have no files written to the disk (want to keep it all stored in my script) and, if possible, not use variable(s) to store any of the raw data.
Another problem is, ogg123 does not support reading from stdin, therefore I can't pipe the any raw ogg data into it.
Commands I have tried: (hex and base64 are truncated of course)
$ ogg123 <<< printf 'xae\x0f\x00\xad\x83' # .ogg data
/usr/local/bin/ogg123: Argument list too long
$ ogg123 <(printf 'xae\x0f\x00\xad\x83') # .ogg data
Error opening /dev/fd/63 using the oggvorbis module. The file may be corrupted.
$ S=<<SOUND
dGhpcyBiYXNlNjQgd291bGQgYmUgdGhlIGJhc2U2NCBvZiBteSBvZ2cgZmlsZQ==
SOUND
$ ogg123 <(echo $S | openssl base64 -d)
Error opening /dev/fd/63 using the oggvorbis module. The file may be corrupted.
$ ogg123 <<< echo $S | openssl base64 -d
5?w?k譸?
I did try several other commands, however I accidentally quit Terminal and those two were the only commands saved in my .bash_history. But believe me, though, everything I tried got me nowhere (I've spent 3.5 hours on this already with no success).
Using macOS High Sierra 10.13.6, bash 3.2.57(1)-release, ogg123 from vorbis-tools 1.4.0, 7za 16.02 (x64), openssl base64 (LibreSSL 2.2.7).
Not a complete fix, but I did get it to work with the following:
mplayer <(openssl base64 -d <<SND
dGhpcyBiYXNlNjQgd291bGQgYmUgdGhlIGJhc2U2NCBvZiBteSBvZ2cgZmlsZQ==
SND
)
Props to mplayer for reading raw data like that (also worked reading from stdin!)
I know that image resizing on the command line is something ImageMagick and similar could do unfortunately I do only have very basic bash scripting abilities so I wonder if this is even possible:
check all directories and subdirectories for all files that are an image
check width and height of the image
if any of both exceeds X amount of pixels resize it to X while keeping aspect ratio.
replace old file with new file (old file shall be removed/deleted)
Thank you for any input.
Implementation might be not so trivial even for advanced users. As a one-liner:
find \ # 1
~/Downloads \ # 2
-type f \ # 3
-exec file \{\} \; \ # 4
| awk -F: '{if ($2 ~/image/) print $1}' \ # 5
| while IFS= read -r file_path; do \ # 6
mogrify -resize 1024x1024\> "$file_path"; \ # 7
done # 8
Lines 1-4 are an invocation of the find command:
Specify a directory to scan.
Specify you need files only.
Per each found item run file command. Example outputs per file:
/Downloads/391A6 625.png: PNG image data, 1024 x 810, 8-bit/color RGB, interlaced
/Downloads/STRUCTURED NODES IN UML 2.0 ACTIVITES.pdf: PDF document, version 1.4
Note how file names are delimited from their info by : and info about PNG contains image word. This also will be true for other image formats.
Use awk to filter only those files which have image word in their info. This gives us image files only. Here, -F: specifies that the delimiter is :. This gives us the variable $1 to contain the original file name and $2 for the file info. We search image word in file info and print file name if it's present.
This one is a bit tricky. Lines 6-8 read the output of awk line by line and invoke the mogrify command to resize images. Here we do not use piping and xargs, as if file paths contain spaces or other characters which must be escaped,
we will get xargs unterminated quote errors and it's a pain to handle that.
Invoke the mogrify command of ImageMagic. Unlike convert, which is also ImageMagic's command, mogrify changes files in-place without creating new ones. Here, 1024x1024\> tells to resize image to have max size of 1024x1024. The \> part tells to preserve aspect ratio, so that the final image will have the biggest side of 1024px. Other side will be smaller than that, unless the original image is square. Pay attention to the ;, as it's needed inside loops.
Note, it's safe to run mogrify several times over the same file: if a file's size already corresponds to your target dimensions, it will not be resized again. However, it will change file's modification time, though.
Additionally, you may need not only to resize images, but to compress them as well. Please, refer to my gist to see how this can be done: https://gist.github.com/oblalex/79fa3f85f05924017d25004496493adb
If your goal is just to reduce big images in size, e.g. bigger than 300K, you may:
find /path/to/dir -type f -size +300k
and as before combine it with mogrify -strip -interlace Plane -format jpg -quality 85 -define jpeg:extent=300KB "$FILE_PATH"
In such case new jpg files will be created for non-jpg originals and originals will need to be removed. Refer to the gist to see how this can be done.
You can do that with a bash unix shell script looping over your directories. You must identify all the file formats you want such as jpg and png, etc. Then for each directory, loop over each file of the given list of formats. Then use ImageMagick to resize the files.
cd
dirlist="path2/directory1 path2/directory2 ...."
for dir in $dirlist; do
cd "$dir"
imglist=`ls | grep -i ".jpg\|.png"`
for img in $imglist; do
convert $img -resize "200x200>" $img
done
done
See https://www.imagemagick.org/script/command-line-processing.php#geometry
Is there a way to modify the contents of a file before a command receives it while maintaining its directory?
mpv 'https://example.com/directory/file.playlist'
but use sed to modify the contents in memory before it is read by mpv?
The issue is I can't just read the file straight in, it must maintain the directory it is in because the files in the playlist are relative to that directory.
I just need to replace .wav with .flac.
Generally you can use process substitution:
mplayer <(curl 'http://...' | sed 's/\.wav/.flac/')
However, mplayer supports the special option - (hyphen) for the filename argument which means read the file from stdin. This allows you to use a pipe:
curl 'http://...' | sed 's/\.wav/.flac/' | mplayer -
So far I'm using this to achieve what I need, but it's not exactly ideal in that I lose my playlist control.
ssh example.com "tar czpf - 'files/super awesome music directory'" | tar xzpf - -O | mpv -
How can I pipe an image into exiv2 or imagemagick, strip the EXIF tag, and pipe it out to stdout for more manipulation?
I'm hoping for something like:
exiv2 rm - - | md5sum
which would output an image supplied via stdin and calcualte its md5sum.
Alternatively, is there a faster way to do this?
Using exiv2
I was not able to find a way to get exiv2 to output to stdout -- it only wants to overwrite the existing file. You could use a small bash script to make a temporary file and get the md5 hash of that.
image.sh:
#!/bin/bash
cat <&0 > tmp.jpg # Take input on stdin and dump it to temp file.
exiv2 rm tmp.jpg # Remove EXIF tags in place.
md5sum tmp.jpg # md5 hash of stripped file.
rm tmp.jpg # Remove temp file.
You would use it like this:
cat image.jpg | image.sh
Using ImageMagick
You can do this using ImageMagick instead by using the convert command:
cat image.jpg | convert -strip - - | md5sum
Caveat:
I found that stripping an image of EXIF tags using convert resulted in a smaller file-size than using exiv2. I don't know why this is and what exactly is done differently by these two commands.
From man exiv2:
rm Delete image metadata from the files.
From man convert:
-strip strip image of all profiles and comments
Using exiftool
ExifTool by Phil Harvey
You could use exiftool (I got the idea from https://stackoverflow.com/a/2654314/3565972):
cat image.jpg | exiftool -all= - -out - | md5sum
This too, for some reason, produces a slightly different image size from the other two.
Conclusion
Needless to say, all three methods (exiv2, convert, exiftool) produce outputs with different md5 hashes. Not sure why this is. But perhaps if you pick a method and stick to it, it will be consistent enough for your needs.
I tested with NEF file. Seems only
exiv2 rm
works best. exiftool and convert can't remove all metadata from .nef FILE.
Notice that the output file of exiv2 rm can no longer be displayed by most image viewers. But I only need the MD5 hash keeps same after I update any metadata of the .NEF file. It works perfect for me.
I am working on an application about windows rdp. Now I get a problem when I try to use the sed command to replace the string of IP address directly in the rdp file. But after executing this command, the origin rdp file is garbled.
sed -i "s/address:s:.*/address:s:$(cat check-free-ip.to.rdpzhitong.rdp)/" rdpzhitong.rdp
I find that the file's format is Little-endian UTF-16 Unicode.
Can I still use the sed command to replace the text in the files correctly? Or other method to process this problem?
If the file is UTF-16 encoded text (as RDP is), and that is not your current encoding (it's not likely to be on Linux) then you can pre- and post-process the file with iconv. For example:
iconv -f utf-16 -t us-ascii <rdpzhitong.rdp |
sed 's/original/modified/' |
iconv -f us-ascii -t utf-16 >rdpzhitong.rdp.modified
if you can cat the file, then you may use sed. no harm in trying before you ask the question.
if the check-free-ip.to.rdpzhitong.rdp file has any text, you may want to do this:
address=$(sed 1q check-free-ip.to.rdpzhitong.rdp)
sed -i "s/address:s:.*/address:s:$address/" rdpzhitong.rdp
also, a little advice. try without the -i switch, until you know it's working.