I have a Mount & Blade: Warband mod called 1257 AD. The mod itself is great, but all the textures have to be resaved to remove mipmaps from dds files, to remove glitches on GNU/Linux. And of course, I could do this manually, but it will took a lot of time(over 2000 textures), and is there any way for gimp to just open and save the file without mipmaps.
Also, last time I wanted to do this I used loop with Imagemagicks convert, but it kept mipmaps. So how do I do this kind of convert?
You should use the 'define' dds:mipmaps if you don't want to keep the mipmaps. Setting it to zero will disable the writing of mipmaps.
convert input.dds -define dds:mipmaps=0 output.dds
You can find a list of all dds defines here: http://www.imagemagick.org/script/formats.php.
If you want to convert them in place, use ImageMagick's mogrify, which is basically convert but does things in-place.
Using mogrify has the potential to irreversibly corrupt your images, so use it wisely and avoid using long strung-out convert-like command lines (use simple commands).
find . -type f -name "*.DDS" | xargs -L1 -I{} mogrify -define dds:mipmaps=0 "{}"
If you're sure you don't have spaces in your pathnames and you want a bit of a speed increase, then just do
find . -type f -name "*.DDS" | xargs mogrify -define dds:mipmaps=0
Related
I'm using convert utility from ImageMagick to convert raw image bytes to usable image format such as PNG. My raw files are generated by code, so there is no any headers, just pure pixels.
In order to convert my image I'm using command:
$ convert -depth 1 -size 576x391 -identify gray:image.raw image.png
gray:image.raw=>image.raw GRAY 576x391 576x391+0+0 1-bit Gray 28152B 0.010u 0:00.009
The width is fixed and pretty known for me. However I have to evaluate the height of the image from the file size each time which is annoying.
Without height specified or if wrong height is specified the utility compains:
$ convert -depth 1 -size 576 -identify gray:image.raw image.png
convert-im6.q16: must specify image size `image.raw' # error/gray.c/ReadGRAYImage/143.
convert-im6.q16: no images defined `image.png' # error/convert.c/ConvertImageCommand/3258.
$ convert -depth 1 -size 576x390 -identify gray:iphone.raw iphone.png
convert-im6.q16: unexpected end-of-file `image.raw': No such file or directory # error/gray.c/ReadGRAYImage/237.
convert-im6.q16: no images defined `image.png' # error/convert.c/ConvertImageCommand/3258.
So I wonder is there a way to automatically detect the image height based on the file/blob size?
A couple of ideas...
You may not be aware of the NetPBM format, but it is very simple and you may be able to change your software that creates the raw images so that it directly generates PBM format images which are readable and useable by OpenCV, Photoshop, GIMP, feh, eog and ImageMagick of course. It would not require any libraries or extra dependencies in your software, all you need to do is put a textual PBM header on the front, so your file looks like this:
P4
576 391
... YOUR EXISTING BINARY DATA ...
Do not forget to put newlines (i.e. linefeed character) after P4 and after 391.
You can try it for yourself and add a header onto one of your files like this and then view it with GIMP or other tool:
printf "P4\n576 391\n" > image.pbm
cat image.raw >> image.pbm
If you prefer a one-liner, just use a bash command grouping like this - which is equivalent to the 2 lines above:
{ printf "P4\n576 391\n"; cat image.raw; } > image.pbm
Be careful to have all the spaces and semi-colons exactly as I have them!
Another idea, just putting some meat on Fred's answer, might be the following one-liner which uses a bash arithmetic context and a bash command substitution, you can do this:
convert -depth 1 -size "576x$(($(stat -c "%s" image.raw)*8/576))" gray:image.raw image.png
Note that if you are on macOS, stat is a little different, so you may prefer the slightly less efficient, but more portable:
convert -depth 1 -size "576x$(($(wc -c < image.raw)*8/576))" gray:image.raw image.png
You have to know the -depth and width to compute the height for ImageMagick raw format. If depth is 1, then your image is binary (b/w). So height = 8 * file size (in B)/(width). 28152*8/391 = 576
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
I need to convert image files with the MINC format (.mnc) to the NIfTI-1 format (.nii).
I want to use the command "mnc2nii" of the minc-tools in Ubuntu bash.
"mnc2nii" requires an input (filename.mnc) and an output (filename.nii).
I have multiple folders and subfolders with MINC files in them.
I am trying to find a way to recursively convert all .mnc files to .nii so that they keep their name and folder structure.
Example:
file abc in /folder/abc.mnc converted to /folder/abc.nii
and
file xyz in /folder/subfolder/xyz.mnc converted to /folder/subfolder/xyz.nii.
Thank you
Untested because it's late here in the UK, so make a backup and test on a copy of a small subset of pictures.
First install GNU Parallel, then in terminal run:
find /path/to/mnc/files -type f -name \*.mnc -print0 |
parallel --dry-run -0 mnc2nii {} {.}.nii
If you like the look, run it again without the --dry-run.
Being GNU Parallel it will do them very fast, in parallel :-)
I'm using the commandline to convert PNG images to a Base64-encoded string. What I'd like to do is to use find to do this on an entire directory.
find ./ -name "*.png" -exec base64 > out.txt {} \;
Rather than storing all the results in one text-file, I'd like to be able to preserve a relation between source-file and result. For both solutions I'm clueless:
Store matched file-name and the Base64-encoded result in one text-file for all matches (e.g. my_file.png = <base64-string>).
Create a text-file for each result, with the filename matching the base-name of the source PNG.
Does the find command offer to make use of it's matched filename through a variable? Can this be done?
If I well understand your problem, you want to convert each *.png file into a base64 one, preserving its name.
Now, this should do the trick:
find . -name "*png" -exec bash -c "base64 {} > {}.txt" \;
Now, let's say you have the files a.png b.png and c.png in your directory. This command will output you:
a.png.txt
b.png.txt
c.png.txt
Where the files are the text files you need.
The problem you were experiencing was actually how to redirect the output within -exec in find, which was solved here: https://superuser.com/questions/231495/how-can-i-use-to-redirect-the-output-of-a-command-run-through-finds-exec
I need to get a specific crop of an image and put it over another image at a certain position and resized.
I can crop the first image and save it to a file in one command and then I can composite the 2 images in another command.
However, I would like to do it in a single command - is this possible with graphicsmagick and how?
Here are the 2 commands I am using atm:
gm convert -crop 1457x973+254+413 amber.jpg tmp.jpg
gm composite -geometry 6000x4000+600+600 tmp.jpg lux_bg.png out.jpg
The reason for wanting this is to avoid writing to disk then reading again when all this could be done in memory.
With ImageMagick, for example, the same 2 commands would be written in a single command like this:
convert lux_bg.png \( amber.jpg -crop 1457x973+254+413 \) -geometry 6000x4000+600+600 -composite out.jpg
I am doing this with ImageMagick for now but would love to do it with GraphicsMagick.
If your reason is simply to avoid creating a temporary file, you can still do it with two commands by constructing 'pipelines' (a great concept invented by, afaik, Douglas McIlroy around 1964):
gm convert -crop 1457x973+254+413 amber.jpg - | gm composite -geometry 6000x4000+600+600 - lux_bg.png out.jpg
hint: note the two - dashes in the two commands, and the | pipe
since the - can be used to mean the standard output and input in the two commands respectively.
This means that no file is created, all should happen in the memory.
You can find this in the help (gm -help convert | grep -i -e out -B 1):
Specify 'file' as '-' for standard input or output.
The use of - is common in unix-likes and must have been inspired by, or by something related to, the POSIX standard's Utility Syntax Guidelines.
Have you tried && operator? Your command should become:
gm convert -crop 1457x973+254+413 amber.jpg tmp.jpg && gm composite -geometry 6000x4000+600+600 tmp.jpg lux_bg.png out.jpg