How to programmatically add a background to a pdf? - python

Given a .pdf file (produced by Inkscape with the LaTeX option, but I am more focused on the .pdf), is there a way to add programmatically a background (ideally, the background would be a rounded rectangle) to it? I am thinking typically of a python script or a C(or objective-C) library.
Typically:
I guess I should be easier to act directly (maybe via the command line) within Inkscape, but I am looking for a solution on the .pdf

If your background is also a PDF, you can use cpdf:
cpdf -stamp-under stamp.pdf input.pdf -o out.pdf

Working further from the answer of johnwhitington I found, that qpdf allows for that as well with the "underlay" option:
qpdf --underlay "background.pdf" -- input.pdf output.pdf
Great advantage: qpdf is available in most distributions. And as allways you can look at qpdf --help to find even more options to specify the page or to work inplace i.e. no need to specify an output file.
Ghostscript and Imagemagick allow for the same, but I found it quite hard to have a proper solution and the .pdf will become a rasterized image.

Related

How to convert .PNG to .SVG in python or shell on Mac Big Sur (tried Inkscape Shell)?

I have a folder with a bunch of .PNG files that I would like to convert to .SVGs. I downloaded Inkscape and was able to manually convert a few of them, but soon I will need to convert a lot of .PNGs to .SVGs and it will not be feasible to do it manually.
I looked into Inkscape's shell feature and activated it as follows on the terminal on Mac Big Sur:
/Applications/Inkscape.app/Contents/MacOS/inkscape --shell
but then when I use this code:
--export-plain-svg /Users/Downloads/pictures/testpic.png
I get the following error:
Unable to find: --export-plain-svg /Users/Downloads/pictures/testpic.png
verbs_action: Invalid verb: --export-plain-svg /Users/Downloads/pictures/testpic.png
(Not a solution, but a clarification)
Inkscape's command-line option --export-plain-svg simply removes some XML metadata from an existing .svg file. The option --export-plain-svgdoes not do this: "import the PNG, automagically converts/"vectorize" it, then export it as SVG."
The feature that you need is called "Trace Bitmap" (Menu Path / Trace Bitmap, or SHIFT+ALT+B) (example). Also the "Fill Bounded Areas" AKA Paint-Bucket Tool (U) can be used for tracing shapes within simple PNGs. Both of these require some manual experimentation first.
Specifically --export-plain-svg removes XML attributes that are in these namespaces:
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
("sodipodi" is a veryold precursor-project name, before the renaming to "Inkscape" happened, AFAIK)
Try https://www.visioncortex.org/vtracer (https://github.com/visioncortex/vtracer)
Opensource tool to convert color pngs to svg, Inkscape is not ok with colors AFAIK

Printing Automation using win32api Python [duplicate]

I'm correcting assignments from my students right now and I'd like to automate an annoying step I always have to do.
After annotating their PDF solutions, I need to Print them to PDF files in order to bake my annotations into the PDF so that they can be included in LaTeX. Right now I have to manually choose "Microsoft Print to PDF" and enter the PDFs name with a leading underscore (which is what my automatically generated LaTeX files expect). This gets annoying for 30+ files.
So I'd like to issue this in a batch-script automatically for all the PDFs to minimize my efforts to a simple double-click. I have seen that this is possible with e.g. C# (Here), but I'd like a solution with a simple batch script.
Can this be done?
Edit:
The C#-Code I found actually does not get the Job done. You can't print existing PDFs that way. I'd need to use Spire.PDF to do that. The Free Version however messes up the PDF; I can download the "Full" version in NuGet, this however generates a disclaimer at the beginning of any PDF, and it still can't handle things I draw in Adobe Reader DC. So C# really is not an option, I need a command-line solution.
You'll better install pdfcreator
and use the commandline options
I assume it should be quite easy using PowerShell, but I ran into the same problem as described in this post.
The PowerShell solution from here creates only blank PDF files for me.
There probably exist better solutions, but I managed to combine PDFtoPrinter and this post.
A batch script could look like this:
for /R %%f in (*.pdf) do (
(echo with createobject^("wscript.shell"^)
echo .run "<path to PDFtoPrinter.exe> ""%%f"""
echo wscript.sleep 3000
echo .sendkeys """%%~df%%~pf%%~nf_correction.pdf"""
echo .sendkeys "{enter}"
echo wscript.sleep 3000
echo end with) > %temp%\sk.vbs
start /w %temp%\sk.vbs
)
This script uses Microsoft Print to PDF to create corresponding files of the format <filename>_correction.pdf.
The batch script creates an sk.vbs script in %temp% and runs it.
The sk.vbs script then handles the file saving dialog of Microsoft Print to PDF.
Additionally, this solution has the drawback that you can't use your computer while the script runs because the sk.vbs script must send keys to the window in focus.

I am looking for a python package which can apply 'resize page to drawing' to a svg files similar to Inkscape

I have a script which uses rdkit to create svg drawings of chemical molecules.
I will use them on a web server, therefore, the size of the figures does matter.
The current output is a string containing the svg file.
I know that I can use Inkscape to remove the white background and "resize page to drawing" which is exactly what I want. But as I am creating quiet a lot of figures I am looking for a way to resize the figures automatically.
My experience with python modules for svg is very limited, therefore I am hoping someone can suggest a module which can apply the needed changes.
I know that I can simply remove the
<rect style='opacity:1.0;fill:#ffffff;stroke:none' width='2000' height='2000' x='0' y='0'> </rect>
part from the svg file to remove the white background, but I have no Idea how to implement the 'resize page to drawing' part.
Any help is highly appreciated.
Inkscape can perform various functions from the command line, including what you are asking for.
My search first led me here:
That is an extensive list of many 'verbs' or actions that Inkscape can do from the command line. There are some linked pages from there but realized that information could be found with Inkscape's command line help
From the command line inkscape --help is very thorough.
The output from the link provided above is just a copy of this command:
inkscape --verb-list.
From that list, what we are looking for is FitCanvasToDrawing
Final Code
inkscape --verb=FitCanvasToDrawing --verb=FileSave --verb=FileClose --verb=FileQuit input.svg
The format for 'verbs' is --verb=VerbName and many different actions can be chained. After all verbs, you provide the filename that Inkscape is going to open/manipulate (unfortunately verbs CANNOT take arguments which would expand the scripting possibilities).
The last verb (FileQuit) in the example above is optional as if you are looping through many files doing this, it will probably be quicker to leave Inkscape open rather than restarting it every couple of seconds.
This last point brings up one of Inkscape's limitations and that is that the UI needs to be open to perform this action which might slow down this process for bigger batches but trivial for one-offs. The bug report for this can be found here and has been marked as a 'Wishlist' item.
Finally, you mention python, but this could be batched out with a shell script by providing a variable at the end instead of a static filename and running that script from the command line on all svg files in a folder like so script *.svg but feel free to use the language you are most comfortable with.

Using Imagemagick without making files?

I'm working in Python to create images from text. I've already been back and forth with PIL and frankly, its font and alignment options need a lot of work.
I can subprocess Imagemagick and it works great, except that it seems to always need to write a file to disk. I would like to subprocess the image creation and just get the data returned to Python, keeping everything in memory.
I've looked into a number of supposed Python wrappers for ImageMagick, but they're all hopelessly years out of date or not documented whatsoever. Even searching extensively on SO doesn't see to clearly point to a defacto way to use ImageMagic with Python. So I think going for subprocessing is the best way forward.
convert and the other ImageMagick commands can output image data to stdout if you specify format:- as the output file. You can capture that output in Python using the subprocess module.
For instance:
cmd = ["convert", "test.bmp", "jpg:-"]
output_stream = subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
It would be a lot more work than piping data to ImageMagick, but there are several Pango based solutions. I used pango and pygtk awhile back, and I am pretty sure you could develop a headless gtk or gdk application to render text to a pixbuf.
A simpler solution might be to use the python cairo bondings.
Pango works at a pretty low level, so simple stuff can be a lot more complicated, but rendering quality is hard to beat, and it gives you a lot of fine grained control over the layout.

Editing Photoshop PSD text layers programmatically

I have a multi-layered PSD, with one specific layer being non-rasterized text. I'm trying to figure out a way I can, from a bash/perl/python/whatever-else program:
load the PSD
edit the text in said layer
flatten all layers in the image
save as a web-friendly format like PNG or JPG
I immediately thought of ImageMagick, but I don't think I can edit the text layer through IM. If I can accomplish the first two steps some other programmatic way, I can always use ImageMagick to perform the last two steps.
After a couple of hours of googling and searching CPAN and PyPI, I still have found nothing promising. Does anyone have advice or ideas on the subject?
If you don't like to use the officially supported AppleScript, JavaScript, or VBScript, then there is also the possibility to do it in Python. This is explained in the article Photoshop scripting with Python, which relies on Photoshop's COM interface.
I have not tried it, so in case it does not work for you:
If your text is preserved after conversion to SVG then you can simply replace it by whatever tool you like. Afterwards, convert it to PNG (eg. by inkscape --export-png=...).
The only way I can think of to automate the changing of text inside of a PSD would be to use a regex based substitution.
Create a very simple picture in Photoshop, perhaps a white background and a text layer, with the text being a known length.
Search the file for your text, and with a hex editor, search nearby for the length of the text (which may or may not be part of the file format).
Try changing the text, first to a string of the same length, then to something shorter/longer.
Open in Photoshop after each change to see if the file is corrupt.
This method, if viable, will only work if the layer in question contains a known string, which can be substituted for your other value. Note that I have no idea whether this will work, as I don't have Photoshop on this computer to try this method out. Perhaps you can make it work?
As for converting to png, I am at a loss. If the replacing script is in Python, you may be able to do it with the Python Imaging Library (PIL, which seems to support it), but otherwise you may just have to open Photoshop to do the conversion. Which means that it probably wouldn't be worth it to change the text pragmatically in the first place.
Have you considered opening and editing the image in The GIMP? It has very good PSD support, and can be scripted in several languages.
Which one you use depends in part on your platform, the Perl interface didn't work on Windows the last I knew. I believe Scheme is supported in all ports.
You can use Photoshop itself to do this with OLE. You will need to install Photoshop, of course. Win32::OLE in Perl or similar module in Python. See http://www.adobe.com/devnet/photoshop/pdfs/PhotoshopScriptingGuide.pdf
If you're going to automate Photoshop, you pretty much have to use Photoshop's own scripting systems. I don't think there's a way around that.
Looking at the problem a different way, can you export from Photoshop to some other format which supports layers, like PNG, which is editable by ImageMagick?
You can also try this using Node.js. I made a PSD command-line tool
One-line command install (needs NodeJS/NPM installed)
npm install -g psd-cli
You can then use it by typing in your terminal
psd myfile.psd -t
You can check out the code to use it from another node script or use it through your shell is from another Bash/Perl/whatever script.

Categories

Resources