How to convert projection of png tile from epsg:4326 to epsg:3857 by one command using gdal - transform

I have tiled png files and those projection is EPSG:4326.
I convert projection to EPSG:3857 with below 2 commands:
gdal_translate -of Gtiff -a_ullr 135.00000000000003 36.59788913307022 140.62500000000003 31.952162238024975 -a_srs EPSG:4326 4326.png 4326.tiff
gdalwarp -s_srs EPSG:4326 -t_srs EPSG:3857 4326.tiff 3857.png
Can I make it with 1 command ?

I don't know how to do it with one command, but if you are working on a Unix-like environment, you can use a pipe to avoid creating an intermediate file.
gdal_translate -of VRT -a_ullr 135.00000000000003 36.59788913307022 140.62500000000003 31.952162238024975 -a_srs EPSG:4326 4326.png /vsistdout/ | \
gdalwarp -t_srs EPSG:3857 /vsistdin/ 3857.png
/vsistdin/ and /vsistdout/ are part of a feature called "GDAL Virtual File Systems", which represents a virtual file that represents standard input and standard output. The output format of gdal_translate could be GTiff, but I tried to use VRT which contains only metadata. If this doesn't work, try changing VRT to GTiff.

Related

CYGWIN, GDAL: batch processing not working; gdalwarp on Cygwin error: "too many points"

I'm attempting to mass convert the Sinusoidal projections of hundreds of MODIS single-band files to WGS84 in a single directory (which were extracted from HDF-EOS format using gdal_translate) using GDAL in Cygwin.
When I execute the gdalwarp command on a single file, it executes the command successfully and the result is my desired output:
$ gdalwarp -s_srs "+proj=sinu +R=6371007.181 +nadgrids=#null +wktext" -t_srs EPSG:4326 testfile.tif testfile_proj_1.tif
Processing testfile.tif [1/1] : 0Using internal nodata values (e.g. -1) for imag
e testfile.tif.
...10...20...30...40...50...60...70...80...90...100 - done.
However, when I try to process the aforementioned hundreds of files using a for loop...:
$ for f in *.tif; do
> gdalwarp -s_srs "+proj=sinu +R=6371007.181 +nadgrids=#null +wktext" -t_srs EPSG:4326 "$f" "${f%.*}.tif"
..., it returns errors:
ERROR 1: Too many points (529 out of 529) failed to transform, unable to compute
output bounds.
Warning 1: Unable to compute source region for output window 0,0,2400,2400, skip
ping.
I am baffled as to why the command will work on a single file, but won't in a mass conversion.
How do I get this to work? Are there any alternatives to GDAL that I can use to mass reproject TIFFs if this is a wall I hit?
Thank you in advance.

Ghostscript command line - pass arguments to included file

I developing pdf conversion app with node.js and Ghostscript. I execute command line gs with exec(). My command definition looks like:
let gs_cmd = `
gs -sDEVICE=pdfwrite \
-dPDFX=true \
-dPDFACompatibilityPolicy=1 \
-sColorConversionStrategy=/CMYK \
-sProcessColorModel=DeviceCMYK \
-sDefaultCMYKProfile=${icc_profile_file} \
-dNoOutputFonts \
-dBATCH \
-dQUIET \
-r${DPI} \
-g${w}x${h} \
-dPDFFitPage \
-NumRenderingThreads=4 \
-o ${target_file}-conv.pdf \
PDFX_def.ps \
#trimbox.in "Trimed" \
${target_file}.pdf
`;
I have problem with line:
#trimbox.in "Trimed" \
which tells to Ghostscript to include file and pass the parameters to in. I can't find a proper way to include parameters that can be used in included file. I want to pass "Trimed" string as $0 argument which will be available in trimbox.in file. I also tried with -t=Trimmed or -t="Trimmed" without effects.
From Ghostscript docs (section 10.1):
#filename
Causes Ghostscript to read filename and treat its contents the same as the command line. (This was intended primarily for getting around DOS's 128-character limit on the length of a command line.) Switches or file names in the file may be separated by any amount of white space (space, tab, line break); there is no limit on the size of the file.
-- filename arg1 ...
-+ filename arg1 ...
Takes the next argument as a file name as usual, but takes all remaining arguments (even if they have the syntactic form of switches) and defines the name ARGUMENTS in userdict (not systemdict) as an array of those strings, before running the file. When Ghostscript finishes executing the file, it exits back to the shell.
How to achieve this?
Running my command causes error:
Error: /undefined in Trimed
Firstly you should review the Ghostscript licence to ensure your use is compliant with the licence (AGPL v3). Note that this includes software as a service applications.
"Trimed" isn't a Ghostscript switch and it isn't the name of an input file, so yes, you get an error. You can't 'pass parameters' to #file, because Ghostscript treats that, literally, as a file containing a bunch of switches. There is no command substitution or anything like that. SO you can't have $0 in the file specified by #file.
So when you say :
#PDFX_def_trimbox.ps "Trimed" \
which tells to Ghostscript to include file and pass the parameters to
in
I'm afraid you are incorrect. There is no way to 'pass parameters' to the file when using the #file syntax.
You haven't said what's in the file 'PDFX_def_trimbox.ps', and I'm suspicious (because of the .ps) that this is a PostScript program. You can't use a PostScript program with the #file syntax, because a PostScript program is not a series of Ghostscript switches.
So where you have :
-sDEVICE=pdfwrite \
-dPDFX=true\
etc, you could put all of those switches into the file specified by #file. But you can't put any PostScript in there.
There are a few other problems. You have specified NumRenderingThreads=4, which will do nothing, because the pdfwrite device doesn't (in general) do any rendering, it preserves the input as far as possible as vector data. So pdfwrite ignores this parameter altogether.
For similar reasons, the -r parameter is less than useful. In the case of pdfwrite that simply affects how accurate the conversion is. You shouldn't set that without good reason.
You've set -sColorConversionStrategy=/CMYK when it should be =-sColorConversionStrategy=CMYK or -dColorConversionStrategy=/CMYK. -s takes strings, -d takes numbers or names.
-g sets teh widht and height of the page in pixels, which isn't a great plan, that depends on the resolution. You should -dDEVICEWIDTHPOINTS and -dDEVICEHEIGHTPOINTS instead, and not set the resolution.
-EDIT-
-response to comment below-
If you want PDF file to contain a 300 dpi image, then you need to create a page which is the correct size so that, when drawn on it, the bitmap data form the image is 300 dpi.
So for example, if you have an image which is 600 pixels by 900 pixels, then in order to get that to be 300 dpi you must make the media size 2 inches by 3 inches, which is 144 by 216 points. Changing the resolution of the pdfwrite device won't affect that at all. Setting -g and -r will alter the media size, but not the resolution of the image, though if you also set -dPDFFitPage then yes it will rescale the image to fit the media, which will alter its resolution.....
I have no idea if your original image was 300 dpi, if it was, and the SVG to PDF conversion maintained that, then you don't need to mess about with media sizes and resolution at all, the pdfwrite device will maintain whatever was there.
As regards the #file syntax, you cannot do this:
-c "[ {ThisPage} << /TrimBox [$0 $1 $2 $3] >> /PUT pdfmark"
in the file supplied via the # comamnd because, as I said, there is no variable replacement in the processing which Ghostscript does on the contents of that file. This is not a bash script.

what is the proper syntax of gmic apply_video

I am trying to apply a gmic filters using apply_video option of gmic utility for linux .
./gmic --apply_video 'small.mp4','-denoise 30,10' -o convert.avi
but the output is an error in terminal
[gmic]-0./ Start G'MIC interpreter.
[gmic]-0./ Apply command 'small.mp4,-denoise 30,10' on video stream '', with output filename '', first frame 0, last frame -1 and frame step 1.
[gmic] *** Error in ./apply_video/*local/*substitute/ *** Command '-basename': Undefined argument '$1', in expression '$1' (for 2 arguments specified).
[gmic] Command '-basename' has the following description:
-basename:
file_path,_variable_name_for_folder
Return the basename of a file path, and opt. its folder location.
When specified 'variable_name_for_folder' must starts by an underscore
(global variable accessible from calling function).
so what is the correct syntax for gmic --apply_video ?
I am using version 1.7.3
I'm using latest available version 1.7.5_pre, and I use it like this :
$ gmic -w -apply_video input.avi,\"-denoise 30,10\",0,-1,1,output.avi
For G'MIC options, you can use the excellent offline help
gmic -h
or
gmic -h -apply_video
Which as of version 1.7.8 gives
gmic: GREYC's Magic for Image Computing.
Version 1.7.8, Copyright (c) 2008-2016, David Tschumperle.
(http://gmic.eu)
-apply_video:
video_filename,_"command",_first_frame>=0,_last_frame={ >=0 | -1=last },
_frame_step>=1,_output_filename
Apply a G'MIC command on all frames of the specified input video file, in a streamed way.
If a display window is opened, rendered frames are displayed in it during processing.
The output filename may have extension '.avi' (saved as a video), or any other usual image file
extension (saved as a sequence of images).
Default values: 'first_frame=0', 'last_frame=-1', 'frame_step=1' and
'output_filename=(undefined)'.

How to edit the exposure of an HDRI image using GraphicsMagick and Node.js?

I have ImageMagick installed with support for HDRI images. Using bash, the following command can be used to save the image with a different number of 'stops' (where stops is a measure of exposure):
stops=`convert xc: -format "%[fx:pow(2,-1)]"`
convert input.exr \
-colorspace RGB \
-function polynomial "$stops,0" \
-gamma 1 \
-colorspace sRGB \
output-minus-one-stop.jpg
In order to do this Node.js, some translation is needed:
var stops = Math.pow(2, -1);
gm('input.exr').colorspace('RGB')
.out(`function polynomial "${stops},0"`)
.gamma(1, 1, 1)
.colorspace('sRGB')
.write('output-minus-one-stop.jpg', function(err){});
However I get the error:
Command failed: convert: unable to open image `function polynomial "0.25,0"': No such file or directory # error/blob.c/OpenBlob/2702
convert: no decode delegate for this image format `25,0"' # error/constitute.c/ReadImage/501
The error is happening because of this line:
.out(`function polynomial "${stops},0"`)
What's the correct way to format the out command in this example?
I don't speak node, but I am fairly familiar with ImageMagick.
The gm you have looks (to me) like GraphicsMagick rather than ImageMagick (the two are different) and I don't think GraphicsMagick has the -function polynomial.
Can you move to IM rather than GM? I may be wrong on either count - and am happy to be corrected if anyone knows better.

How to convert a SVG to a PNG with ImageMagick?

I have a SVG file that has a defined size of 16x16. When I use ImageMagick's convert program to convert it into a PNG, then I get a 16x16 pixel PNG which is way too small:
convert test.svg test.png
I need to specify the pixel size of the output PNG. -size parameter seems to be ignored, -scale parameter scales the PNG after it has been converted to PNG. The best result up to now I got by using the -density parameter:
convert -density 1200 test.svg test.png
But I'm not satisfied, because I want to specify the output size in pixels without doing math to calculate the density value. So I want to do something like this:
convert -setTheOutputSizeOfThePng 1024x1024 test.svg test.png
So what is the magic parameter I have to use here?
I haven't been able to get good results from ImageMagick in this instance, but Inkscape does a nice job of scaling an SVG on Linux and Windows:
# Inkscape v1.0+
inkscape -w 1024 -h 1024 input.svg -o output.png
# Inkscape older than v1.0
inkscape -z -w 1024 -h 1024 input.svg -e output.png
Note that you can omit one of the width/height parameters to have the other parameter scaled automatically based on the input image dimensions.
Here's the result of scaling a 16x16 SVG to a 200x200 PNG using this command:
Try svgexport:
svgexport input.svg output.png 64x
svgexport input.svg output.png 1024:1024
svgexport is a simple cross-platform command line tool that I have made for exporting svg files to jpg and png, see here for more options. To install svgexport install npm, then run:
npm install svgexport -g
Edit: If you find an issue with the library, please submit it on GitHub, thanks!
This is not perfect but it does the job.
convert -density 1200 -resize 200x200 source.svg target.png
Basically it increases the DPI high enough (just use an educated/safe guess) that resizing is done with adequate quality. I was trying to find a proper solution to this but after a while decided this was good enough for my current need.
Note: Use 200x200! to force the given resolution
Inkscape doesn't seem to work when svg units are not px (e.g. cm). I got a blank image. Maybe, it could be fixed by twiddling the dpi, but it was too troublesome.
Svgexport is a node.js program and so not generally useful.
Imagemagick's convert works ok with:
convert -background none -size 1024x1024 infile.svg outfile.png
If you use -resize, the image is fuzzy and the file is much larger.
BEST
rsvg-convert -w 1024 -h 1024 infile.svg -o outfile.png
It is fastest, has the fewest dependencies, and the output is about 30% smaller than convert. Install librsvg2-bin to get it:
sudo apt install -y librsvg2-bin
There does not appear to be a man page but you can type:
rsvg-convert --help
to get some assistance. Simple is good.
If you are on MacOS X and having problems with Imagemagick's convert, you might try reinstalling it with RSVG lib.
Using HomeBrew:
brew remove imagemagick
brew install imagemagick --with-librsvg
Verify that it's delegating correctly:
$ convert -version
Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-12-17 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules
Delegates: bzlib cairo fontconfig freetype jng jpeg lcms ltdl lzma png rsvg tiff xml zlib
It should display rsvg.
After following the steps in Jose Alban's answer, I was able to get ImageMagick to work just fine using the following command:
convert -density 1536 -background none -resize 100x100 input.svg output-100.png
The number 1536 comes from a ballpark estimate of density, see this answer for more information.
In order to rescale the image, the option -density should be used. As far as I know the standard density is 72 and maps the size 1:1. If you want the output png to be twice as big as the original svg, set the density to 72*2=144:
convert -density 144 source.svg target.png
In ImageMagick, one gets a better SVG rendering if one uses Inkscape or RSVG with ImageMagick than its own internal MSVG/XML rendered. RSVG is a delegate that needs to be installed with ImageMagick. If Inkscape is installed on the system, ImageMagick will use it automatically. I use Inkscape in ImageMagick below.
There is no "magic" parameter that will do what you want.
But, one can compute very simply the exact density needed to render the output.
Here is a small 50x50 button when rendered at the default density of 96:
convert button.svg button1.png
Suppose we want the output to be 500. The input is 50 at default density of 96 (older versions of Inkscape may be using 92). So you can compute the needed density in proportion to the ratios of the dimensions and the densities.
512/50 = X/96
X = 96*512/50 = 983
convert -density 983 button.svg button2.png
In ImageMagick 7, you can do the computation in-line as follows:
magick -density "%[fx:96*512/50]" button.svg button3.png
or
in_size=50
in_density=96
out_size=512
magick -density "%[fx:$in_density*$out_size/$in_size]" button.svg button3.png
On macOS using brew, using librsvg directly works well
brew install librsvg
rsvg-convert test.svg -o test.png
Many options are available via rsvg-convert --help
For simple SVG to PNG conversion I found cairosvg (https://cairosvg.org/) performs better than ImageMagick. Steps for install and running on all SVG files in your directory.
pip3 install cairosvg
Open a python shell in the directory which contains your .svg files and run:
import os
import cairosvg
for file in os.listdir('.'):
name = file.split('.svg')[0]
cairosvg.svg2png(url=name+'.svg',write_to=name+'.png')
This will also ensure you don't overwrite your original .svg files, but will keep the same name. You can then move all your .png files to another directory with:
$ mv *.png [new directory]
why don't you give a try to inkscape command line, this is my bat file to convert all svg in this dir to png:
FOR %%x IN (*.svg) DO C:\Ink\App\Inkscape\inkscape.exe %%x -z --export-dpi=500 --export-area-drawing --export-png="%%~nx.png"
This is what worked for me and would be the easiest to run.
find . -type f -name "*.svg" -exec bash -c 'rsvg-convert -h 1000 $0 > $0.png' {} \;
rename 's/svg\.png/png/' *
This will loop all the files in your current folder and sub folder and look for .svg files and will convert it to png with transparent background.
Make sure you have installed the librsvg and rename util
brew install librsvg
brew install rename
Transparent background, exported at target height/size using ImageMagick 7:
magick -background none -size x1080 in.svg out.png
One-liner mass converter:
for i in *svg; do magick -background none -size x1080 "$i" "${i%svg}png"; done
I came to this post - but I just wanted to do the conversion by batch and quick without the usage of any parameters (due to several files with different sizes).
rsvg drawing.svg drawing.png
For me the requirements were probably a bit easier than for the original author. (Wanted to use SVGs in MS PowerPoint, but it doesn't allow)
Without librsvg, you may get a black png/jpeg image. We have to install librsvg to convert svg file with imagemagick.
Ubuntu
sudo apt-get install imagemagick librsvg
convert -density 1200 test.svg test.png
MacOS
brew install imagemagick librsvg
convert -density 1200 test.svg test.png
One thing that just bit me was setting the -density AFTER the input file name. That didn't work. Moving it to the first option in convert (before anything else) made it work (for me, YMMV, etc).
On Linux with Inkscape 1.0 to convert from svg to png need to use
inkscape -w 1024 -h 1024 input.svg --export-file output.png
not
inkscape -w 1024 -h 1024 input.svg --export-filename output.png
I've solved this issue through changing the width and height attributes of the <svg> tag to match my intended output size and then converting it using ImageMagick. Works like a charm.
Here's my Python code, a function that will return the JPG file's content:
import gzip, re, os
from ynlib.files import ReadFromFile, WriteToFile
from ynlib.system import Execute
from xml.dom.minidom import parse, parseString
def SVGToJPGInMemory(svgPath, newWidth, backgroundColor):
tempPath = os.path.join(self.rootFolder, 'data')
fileNameRoot = 'temp_' + str(image.getID())
if svgPath.lower().endswith('svgz'):
svg = gzip.open(svgPath, 'rb').read()
else:
svg = ReadFromFile(svgPath)
xmldoc = parseString(svg)
width = float(xmldoc.getElementsByTagName("svg")[0].attributes['width'].value.split('px')[0])
height = float(xmldoc.getElementsByTagName("svg")[0].attributes['height'].value.split('px')[0])
newHeight = int(newWidth / width * height)
xmldoc.getElementsByTagName("svg")[0].attributes['width'].value = '%spx' % newWidth
xmldoc.getElementsByTagName("svg")[0].attributes['height'].value = '%spx' % newHeight
WriteToFile(os.path.join(tempPath, fileNameRoot + '.svg'), xmldoc.toxml())
Execute('convert -background "%s" %s %s' % (backgroundColor, os.path.join(tempPath, fileNameRoot + '.svg'), os.path.join(tempPath, fileNameRoot + '.jpg')))
jpg = open(os.path.join(tempPath, fileNameRoot + '.jpg'), 'rb').read()
os.remove(os.path.join(tempPath, fileNameRoot + '.jpg'))
os.remove(os.path.join(tempPath, fileNameRoot + '.svg'))
return jpg
The top answer by #808sound did not work for me. I wanted to resize
and got
So instead I opened up Inkscape, then went to File, Export as PNG fileand a GUI box popped up that allowed me to set the exact dimensions I needed.
Version on Ubuntu 16.04 Linux:
Inkscape 0.91 (September 2016)
(This image is from Kenney.nl's asset packs by the way)
I was getting "low poly" curves using the general approach of increasing the density. So I decided to dig a little deeper and solve that problem as it seemed to be a side effect of this approach and I think it has to do with the original density or dpi.
We have seen 72 in this answer and 96 in this answer being suggested as the default density of an image, but which one? what if mine is different?
ImageMagick has a way to sort that out:
identify -verbose test.svg
this will put out a lot of metadata about the image file, including:
Image:
Filename: test.svg
Format: SVG (Scalable Vector Graphics)
Mime type: image/svg+xml
Class: ...
Geometry: ...
Resolution: 37.79x37.79
Print size: ...
Units: PixelsPerCentimeter
# and a whole lot MORE ...
for a more concise query you can try:
identify -format "%x x %y %U" test.svg
=> 37.789999999999999147 x 37.789999999999999147 PixelsPerCentimeter
as suggested by this forum post and modified with this documentation
Now we know the current density of the image but may need to convert it to the correct units for conversion or mogrifying (PixelsPerInch or dpi)
this is a simple calculations of PixelsPerCentimeter x 2.54
37.789999999999999147 x 2.54 = 95.9866 ~> 96
if you prefer a chart or online calculator for this you can try https://www.pixelto.net/cm-to-px-converter.
now that we have the right original density converted to dpi, the rest of the logic stated in the above answers falls into place and the svg file can be scaled to a better "resolution" by multiplying the original density.
the original density was far too pixelated as a png for me, so in my case 5x the original density or -density 480 was good enough for me. Remember that this resizes the image as well and you will need to adjust for that when using / implementing the image as compared to the original svg.
NOTE: I did try the Inkscape approaches as well and also had the pixelation problem, but had already seen an improvement with the density approach so I decided to dig into that deeper. The output of the Inkscape attempt however gave me the idea, which you can also use for determining the dpi, but that is a lot to install just to get something you can already get with ImageMagick
Area 0:0:20.75:17 exported to 21 x 17 pixels (96 dpi)

Resources