Smooth PostScript animations - animation

I would like to run animations in PostScript smoothly. To see what I want, let me switch to PostScript directly. Call ghostscript, and
200 dup scale .5 setgray 0 0 3 3 rectfill
We have now a gray square.
0 setgray 0 1 3 1 rectfill
With a black stripe in it. We will now fill that stripe, one time white
and black in succession:
{1 setgray 0 1 3 1 rectfill 0 setgray 0 1 3 1 rectfill} loop
You will see now some flickering of black and white rectangles that
are smaller than the original black stripe. Ideally, we would see
the original grey square. Or almost. Where can I get such functionality today?
To see a more interesting animation sequence searching for magic
squares of size 5:
wget http://www.complang.tuwien.ac.at/ulrich/gupu/l5.eps.gz
zcat l5.eps.gz | ghostscript -
A couple of years ago I did try to address these issues. But it never went into ghostscript or Xfree. See
this page. Maybe there are some better ideas now?
Edit: After reading the responses so far, let me clarify one issue here. Essentially, there are two independent issues in this question:
How should an animation be viewed from the language level? I believe, the best way is to view each frame as a single page. With copypage incremental changes can be realized with low effort. Sadly, that semantics of copypage is only present in Level 1 and 2. In Level 3, the meaning of copypage changed to showpage. I did - many years ago - a little modification to ghostscript to delay all visible changes up to copypage or showpage. In this manner, a single XCopyArea containing the changed area is performed locally on the server (that is, the display).
How should actual changes on the visual display be synchronized to avoid artefacts that where not present in the graphics described? The irregular flicker you see is not a privilege of PostScript, it seems to be present in any double-buffered system I have seen so far. Just try to program this in whatever system you see fit.
Further edit:
To get the right language level, that is level 1 or 2 do (for ghostscript):
systemdict /.setlanguagelevel known {2 .setlanguagelevel} if
Edit: I am adding this comment to may attract some new postscript contributors.

We explored some of these issues in this thread on comp.lang.postscript.
Since the release of the Level 2 standard, Postscript is a garbage-collected language. You can disable collection of user objects with the fragment -2 vmreclaim, but it doesn't accomplish much. You can disable ALL ghostscript garbage collection by invoking with the -dNOGC option. This should help prevent stalling and spitting with parts of the image.
Ghostscript has a non-standard operator called flushpage, which synchronizes the rendering with the execution. This helps make sure that everything is seen before it's gone.
- flushpage -
On displays, flushes any buffered output, so that it is guaranteed to
show up on the screen; on printers, has no effect
And for timing control, there doesn't seem to be a better way than simple busy-waiting.
/smallpause {
/flushpage where{pop flushpage}if
50 sleep } def
/pagepause {
/flushpage where{pop flushpage}if
1000 sleep } def
/sleep {
usertime add {
10 {
1 100000 div pop %busy
.1 sin 257 cos atan pop %busy busy
} repeat
dup usertime le {exit}if
} loop pop
} def
The where guards around flushpage allow you to send the same code to interpreters other than ghostscript (like a printer).
If you had an actual Display Postscript server, you could use the wait operator instead of busy-waiting.

Although I like (and upvoted) #luserdroog's answer, I don't believe Postscript should be used for animations on this way - I'd rather use some language that can run widgets or display elements that are designed for real time display and user interation - that is not the case of postscript or ghostscript.
I think it would be nice, though, use postscript for aimations for rendering purposes - just rendering a page after each modification on the image, and using an external program to assemble the different pages as animation frames.
Maybe even using postscript as a rendering engine, with the process in another language calling ghostscript to render each frame in realtime. A nice and easy to use multimedia framework to do that could be for example, the Python language with the Pygame module.
Here is a short example using "pure python + pygame".
#! /usr/bin/env python
# coding: utf-8
import pygame
size = 640,480 #(in pixels)
# multiplying factor so that the whole image is 5 units across
factor = size[0] / 5.0
# Inits pygame drawing window
screen = pygame.display.set_mode(size)
# Rectangle drawing function that scales drawing using the factor above
def draw_rect(color, rect):
new_rect = [int (r * factor) for r in rect]
return pygame.draw.rect(screen, color, new_rect)
def main():
draw_rect((128,128,128), (0, 0, 3, 3))
colors = ((255,255,255), (0,0,0))
color_index = 0
while True:
draw_rect(colors[color_index], (0, 1, 3, 1))
pygame.display.flip()
color_index = 1 - color_index
pygame.time.delay(50) # in miliseconds
try:
main()
finally:
pygame.quit()
To execute this, you have to have Python and Pygame (from http://pygame.org - there are ready packages on most linux systems for that)
Pygame's drawing API is much poorer than postscript - if you need more than rectangles
(like bezies, scaling, rotating and shearing the coordinate system, and so on), the way to go is to use Cairo + python + some display library (which might be pygame, GTK+ or qt) . Cairo is a 2D drawing library that inherits from the postscript way. - or, as I said above, to drive a ghostscript external process using Python, having it generating a rle compressed image file to stdout or a ramdrive, and that image read and displayed frame by frame using python + pygame.
Another option is to use HTML5's Canvas, and do everything in Javascript, viewable on a browser. HTML5's Canvas also inherits the Postscript way of drawing.

Related

extracting images from PDF with page and screen coordinate information

I want to extract images from PDFs retaining a knowledge of their content (page_number and coordinates on page). (Some tools (e.g. pdfminer) only emit image files with non-semantic names, e.g. Img0.bmp). I can do this with PDFBox (Java) but I'd ideally like a Python tool
My current (arbitrary) designs is to create filenames of the form:
image_<page>_<serial_in_page>_<x1>_<x2>__<y1>_<y2>.png
Currently pdfplumber exposes cooordinates but with a PDFStream and encoding information rather than an image. Code to convert the stream to a *.png would solve the problem.
(NOTE: the pdfplumber approach of rendering to the screen and capturing the known rectangle (which I use) is not a solution as the image is often degraded and frequently overwritten with text.)
(NOTE: I have had problems with several Python tools (pdfminer.six, PuMuPDF) extracting images as they make the background black which obscures black text, etc. PDFBox (Java) doesn't have this problem.)
Python tools are likely to have similar problems to any tools even those that require a single line to manipulate images or extract their details.
Here we can see a visual layout of all the compressed images in the file by using one command line to extract images. Here the individual object references have been converted into normal tiff or jpg (other tools may use pbm and pgm especially for OCR but the result is generally similar). The Greyscale Alpha softmask (B&W) transparency components are not necessarily tied direct to a page or an image other than by internal references, and usually appear like negatives.
What you may note is that the objects that were inserted most likely as one PNG are broken in two when injected into the PDF and their scaled placement is defined. Note that a raw PNG (whatever its source common resolution was) will retain number of dots but its scale when inserted into the PDF could be totally different horizontal and vertical, thus the only meaningful data is W x H in pixel values.
It is not trivial to overlay the mask on the RGB component when simply extracted but can allow for colour changes if desired.
So PDFbox is one of the simpler/better tools for blending to a suitable output, (as you have discovered) but for Python it is generally the top end library products that can identify the placement of the two images and combine into a suitable alpha output like a new PNG.
For many suggestions see Extract images from PDF without resampling, in python?.
Your related part question was knowing where those components are placed on each page since one image (and its alpha mask) could be placed multiple times such as a heading logo on each page. Again it is easy in a single command line to see which pages are referenced by a group of images, but to see which image is placed where requires analyzing each pages resources, again requiring a library interrogation of page contents, thus best done via power house libraries such as iText or any other like PDFtron for python.
For a related command in PyMuPDF see https://pymupdf.readthedocs.io/en/latest/page.html#Page.get_image_rects
I don't have a solution in Python but here is a small script using Ruby and HexaPDF:
require 'hexapdf'
class ImageBorderProcessor < HexaPDF::Content::Processor
def initialize(page, index)
super()
#page = page
#index = index
#count = 0
end
def paint_xobject(name)
super
xobject = resources.xobject(name)
return unless xobject[:Subtype] == :Image
w, h = xobject.width, xobject.height
llx, lly = graphics_state.ctm.evaluate(0, 0)
lrx, lry = graphics_state.ctm.evaluate(1, 0)
urx, ury = graphics_state.ctm.evaluate(1, 1)
ulx, uly = graphics_state.ctm.evaluate(0, 1)
# If the image is rotated, you will need all 4 coordinates, nut just the 2
filename = "image_#{#index}_#{#count}_#{llx}_#{urx}_#{lly}_#{ury}"
xobject.write(filename) rescue puts "Can write image #{#index}-#{#count}"
#count += 1
end
end
doc = HexaPDF::Document.open(ARGV[0])
doc.pages.each_with_index do |page, index|
processor = ImageBorderProcessor.new(page, index)
page.process_contents(processor)
end
It will iterate over all pages of the input document provided on the command line and create files using your file naming scheme. Since HexaPDF doesn't currently support writing all types of PDF images, you might get some error messages for those that can't be written.
If a supported image has an associated image mask defined, it will automatically be used to create a transparent image.
The script will output all images found, even repeated ones. This could easily be changed so that just a soft link is created for repeated images.

Use cuda to get screenshot of visible application

I am owner of a Nvidia GTX 1060. I know that with Windows it is not possible to directly access the video memory of the graphics card. But I read somewhere on an email list that it is possible to fetch the pixels that are displayed right now on the monitor with use of the CUDA API. Unfortunately I found no code example for this.
What I want is something like an bitmap-like array containing the rgb values of the pixels
arr[0] = 255 // red
arr[1] = 255 // green
arr[2] = 0 // blue
arr[3] = 0 // alpha
arr[4] = 255
...
Can someone please show me an example how to do it with CUDA?
I know there is a way using DirectX or openGL. I already tried it out but it is either too complex or too slow and won't work with fullscreen and windowed applications at the same time.
What you are describing is not only impossible, it may be even seen as a security flaw. In general, one application should not be able to retrieve the shown window of another application without some kind of consent and control from the operating system.
I remember reading about exactly that kind of a flaw few years ago, but I couldn't find the article anymore. However, there are many other articles discussing similar issues. For example in:
http://ece.neu.edu/groups/nucar/NUCARTALKS/snp14-gpusteal.pdf
they discuss GPU vulnerabilities allowing a malicious program to partially reconstruct a webpage shown in Chromium.

Matplotlib Plots Lose Transparency When Saving as .ps/.eps

I'm having an issue with attempting to save some plots with transparent ellipsoids on them if I attempt to save them with .ps/.eps extensions.
Here's the plot saved as a .png:
If I choose to save it as a .ps/.eps here is what it looks like:
How I got around this, was to use ImageMagick to convert the original png to a ps. The only problem is that the image in png format is about 90k, and it becomes just under 4M after conversion. This is not good since I have a lot of these images, and it will take too much time to compile my latex document. Does anyone have a solution to this?
The problem is that eps does not support transparencies natively.
There are few options:
rasterize the image and embed in a eps file (like #Molly suggests) or exporting to pdf and converting with some external tool (like gs) (which usually relies as well on rasterization)
'mimic' transparency, giving a colour that looks like the transparent one on a given background.
I discussed this for sure once on the matplotlib mailing list, and I got the suggestion to rasterize, which is not feasible as you get either pixellized or huge figures. And they don't scale very nicely when put into, e.g., a publication.
I personally use the second approach, and although not ideal, I found it good enough. I wrote a small python script that implements the algorithm from this SO post to obtain a solid RGB representation of a colour with a give transparency
EDIT
In the specific case of your plot try to use the zorder keyword to order the parts plotted. Try to use zorder=10 for the blue ellipse, zorder=11 for the green and zorder=12 for the hexbins.
This way the blue should be below everything, then the green ellipse and finally the hexbins. And the plot should be readable also with solid colors. And if you like the shades of blue and green that you have in png, you can try to play with mimic_alpha.py.
EDIT 2
If you are 100% sure that you have to use eps, there are a couple of workarounds that come to my mind (and that are definitely uglier than your plot):
Just draw the ellipse borders on top of the hexbins.
Get centre and amplitude of each hexagon, (possibly discard all zero bins) and make a scatter plot using the same colour map as in hexbin and adjusting the marker size and shape as you like. You might want to redraw the ellipses borders on top of that
Another alternative would be to save them to pdf
savefig('myfigure.pdf')
That works with pdflatex, if that was the reason why you needed to use eps and not svg.
You can rasterize the figure before saving it to preserve transparency in the eps file:
ax.set_rasterized(True)
plt.savefig('rasterized_fig.eps')
I had the same problem. To avoid rasterizing, you can save the image as a pdf and then run (on unixish systems at least) in a terminal:
pdftops -eps my.pdf my.eps
Which gives a .eps file as output.
I solved this by:
1) adding a set_rasterization_zorder(1) when defining the figure area:
fxsize=16
fysize=8
f = figure(num=None, figsize=(fxsize, fysize), dpi=180, facecolor='w',
edgecolor='k')
plt.subplots_adjust(
left = (18/25.4)/fxsize,
bottom = (13/25.4)/fysize,
right = 1 - (8/25.4)/fxsize,
top = 1 - (8/25.4)/fysize)
subplots_adjust(hspace=0,wspace=0.1)
#f.suptitle('An overall title', size=20)
gs0 = gridspec.GridSpec(1, 2)
gs11 = gridspec.GridSpecFromSubplotSpec(1, 1, subplot_spec=gs0[0])
ax110 = plt.Subplot(f, gs11[0,0])
f.add_subplot(ax110)
ax110.set_rasterization_zorder(1)
2) a zorder=0 in each alpha=anynumber in the plot:
ax110.scatter(xs1,ys1 , marker='o', color='gray' , s=1.5,zorder=0,alpha=0.3)#, label=label_bg)
and
3) finally a rasterized=True when saving:
P.savefig(str(PLOTFILENAME)+'.eps', rasterized=True)
Note that this may not work as expected with the transparent keyword to savefig because an RGBA colour with alpha<1 on transparent background will be rendered the same as the RGB colour with alpha=1.
As mentioned above, the best and easiest choice (if you do not want to loose resolution) is to rasterized the figure
f = plt.figure()
f.set_rasterized(True)
ax = f.add_subplot(111)
ax.set_rasterized(True)
f.savefig('figure_name.eps',rasterized=True,dpi=300)
This way, you can manage the size by dpi option as well. In fact, you can also play with the zorder below you want to apply the rasterization:
ax.set_rasterization_zorder(0)
Note: It is important to keep f.set_rasterized(True) when you use plt.subplot and plt.subplot2grid functions. Otherwise, label and tick area will not appear in the .eps file
My solution is to export the plot as .eps, load it up to Inkscape for example, then Ungroup the plot, select the object that I want to set the transparency and just edit the Opacity of the Fill in the "Fill and Stroke" tab.
You can save the file as .svg if you want to tweak it later, or export the image for a publication.
If you are writing the academic paper in latex, I would recommend you export the .pdf file rather than .eps. The .pdf format supports transparency perfectly and has good compression efficiency, and most importantly, can be easily edited in Adobe Illustrator.
If you wanna further edit the graph (NOT EDITING DATA! I MEAN, FOR GOOD-LOOKING), you could open the exported graph, in Adobe Acrobat - Edit - Copy elements into Adobe Illustrator. The two software can handle everything perfectly.
I work happily with this method. Everything clear, editable and small-size. Hope can help.

Recreating AS3 Color Transformations on server-side JPG

oh wise list,
We need a scalable solution that can handle many concurrent requests for recreating color transformations done on a low-res jpeg in Flash --> a high-resolution jpeg on the server.
I want to create the following process : http://cl.ly/24371N3f0g0W041R380f
Should we send this data to GDLibrary? ImageMagic? and server-side Air app?
or perhaps use C++ libs in the client flash app? and send those to transformation commands to the C++ app on the server to use on the high-res image?
thank you!
First off, how crazzy is your color transformation? Is it just ColorTransform/ColorMatrix?
Image Magic has colorize functions and color transformation functions.
http://www.imagemagick.org/script/command-line-options.php?#colorize
Specify the amount of colorization as a percentage. Separate colorization values can be applied to the red, green, and blue channels of the image with a comma-delimited list of colorization values (e.g., -colorize 0,0,50).
However, this will only get you so far, as this is only the r/g/b multipliers, not the offsets. For offsets, you'd have to create your own custom function to loop through the libs. ColorTransform is fairly simple --
it's either: color * multiplier + offset or (color + offset) * multiplier
Stay away from a server side air app -- I would go with a custom already geared towards servers ... ImageMagick, (I personally prefer GMagick, which is the same pretty much)

Embedding matlab plot in pdf for printing: Sizes

I'm currently creating my figures in matlab to embed themvia latex into a pdf for later printing. I save the figures and save them via the script export_fig! Now I wonder which is the best way to go:
Which size of the matlab figure window to chose
Which -m option to take for the script? It will change the resolution and the size of the image...
I'm wondering about those points in regards to the following two points:
When chosing the figure-size bigger, there are more tickmarks shown and the single point markers are better visible
When using a small figure and using a big -m option, I still have only some tickmarks
When I generate a image which is quite huge (e.g. resolution 300 and still 2000*2000px) and than embed it into the document: Does this than look ugly? Will this be embedded in a nice scaling mode or is it the same ugliness as if you upload a 1000*1000px image onto a homepage and embed it via the widht and height tags in html -> the browser displays it quite ugly because the browser doesn't do a real resize. So it looks unsharp and ugly.
Thanks in advance!
The MATLAB plots are internally described as vector graphics, and PDF files are also described using vector graphics. Rendering the plot to a raster format is a bad idea, because you end up having to choose resolution and end up with bigger files.
Just save the plot to EPS format, which can be directly embedded into a PDF file using latex. I usually save my MATLAB plots for publication using:
saveas(gcf, 'plot.eps', 'epsc');
and embed them directly into my latex file using:
\includegraphics[width=0.7\linewidth]{plot.eps}
Then, you only need to choose the proportion of the line the image is to take (in this case, 70%).
Edit: IrfanView and others (XnView) don't display EPS very well. You can open them in Adobe Illustrator to get a better preview of what it looks like. I always insert my plots this way and they always look exactly the same in the PDF as in MATLAB.
One bonus you also get with EPS is that you can actually specify a font size so that the text is readable even when you resize the image in the document.
As for the number of ticks, you can look at the axes properties in the MATLAB documentation. In particular, the XTick and YTick properties are very useful manually controlling how many ticks appear no matter what the window resolution is.
Edit (again): If you render the image to a raster format (such as PNG), it is preferable to choose the exact same resolution as the one used in the document. Rendering a large image (by using a big window size) and making it small in the PDF will yield bad results mainly because the size of the text will scale directly with the size of the image. Rendering a small image will obviously make for a very bad effect because of stretching.
That is why you should use a vector image format. However, the default MATLAB settings for figures produce some of the same problems as raster images: text size is not specified as a font size and the number of ticks varies with the window size.
To produce optimal plots in the final render, follow the given steps:
Set the figure's font size to a decent setting (e.g. 11pt)
Render the plot
Decide on number of ticks to get a good effect and set the ticks manually
Render the image to color EPS
In MATLAB code, this should look somewhat like the following:
function [] = nice_figure ( render )
%
% invisible figure, good for batch renders.
f = figure('Visible', 'Off');
% make plots look nice in output PDF.
set(f, ...
'DefaultAxesFontSize', 11, ...
'DefaultAxesLineWidth', 0.7, ...
'DefaultLineLineWidth', 0.8, ...
'DefaultPatchLineWidth', 0.7);
% actual plot to render.
a = axes('Parent', f);
% show whatever it is we need to show.
render(a);
% save file.
saveas(f, 'plot.eps', 'epsc');
% collect garbarge.
close(f);
end
Then, you can draw some fancy plot using:
function [] = some_line_plot ( a )
%
% render data.
x = -3 : 0.001 : +3;
y = expm1(x) - x - x.^2;
plot(a, x, y, 'g:');
title('f(x)=e^x-1-x-x^2');
xlabel('x');
ylabel('f(x)');
% force use of 'n' ticks.
n = 5;
xlimit = get(a, 'XLim');
ylimit = get(a, 'YLim');
xticks = linspace(xlimit(1), xlimit(2), n);
yticks = linspace(ylimit(1), ylimit(2), n);
set(a, 'XTick', xticks);
set(a, 'YTick', yticks);
end
And render the final output using:
nice_figure(#some_line_plot);
With such code, you don't need to worry about the window size at all. Notice that I haven't even showed the window for you to play with its size. Using this code, I always get beautiful output and small EPS and PDF file sizes (much smaller than when using PNG).
The only thing this solution does not address is adding more ticks when the plot is made larger in the latex code, but that can't be done anyways.

Resources