Python / PIL - Raw RGB565 data to PNG? - python-3.x

I have raw RGB565 data as a bytes-like object and I want to save it as a PNG.
Although it is possible with libraries such as PyQt5, as you can here:
QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB16)
I would like to use only PIL, but I cannot find a way to do this with only PIL.
More generally, a method that does not involve Qt would be fine.
Thanks.

It so happens that the pypng repository has a tool to convert from Kobo's 15-bit to PNG.
It's here: https://github.com/drj11/pypng/blob/master/code/kobo565topng
One word of warning however, it outputs an 8-bit RGB PNG.
You don't save any space by saving it as an R5G6B5 PNG, so that might not matter much.

Related

Converting sequence of SVG images (which contain Emojis) to a MPEG video

I googled and even asked chatGPT but I'm unable to find a solution and hope to get some guidance here.
First I've to mention that I'm not a programmer but rather a beginner.
Following a short description of what I'm trying to achive and what I've done so far.
I gather data and create a circular visualization using Circos which produces SVG
and PNG images.
(unfortunately the PNG doesn't give me the option of searching for
text an make replaecments), nevertheless I can use them to sucessfuly produce a
MPEG movie using FFmpeg. Therefore I need to use the SVG output to apply the
desired changes.
So I tried to use CairoSVG to render the SVG file to a PNG image but it does not
render emojis by default because the are not part of the SVG specification and
CairoSVG only supports features defined in the SVG specification. The Emojis are
stored as Unicode characters and are not natively supported in SVG
Next I tried to use PIL (Python Imaging Library) as it provides support for Unicode
characters, including emojis, when converting images to and from various formats.
Unfortunately PIL does not have native support for converting SVG files to PNG and
it seems that PIL is primarily designed for creating and manipulating images in a
variety of formats, but does not have built-in support for reading or converting
SVG files.
So now my questions are:
Would FFmpeg give me the desired results, if I compile it using the --enable-
librsvg option so it can convert a sequence of SVG images to a video but i'm not
sure if it supports emojis rendered correctly and want to spare me the hassle as
I'm pretty sure to struggle compiling it on my Mac running Ventura?
Are the maybe other ways or posibilities to solve that problem?
Many thanks in advance for your help or any hint :-)
Have all a nice weekend and take care
Regards,
Deekee
NB: an example of the circular visualization can be found here animated graph and the static version annotated graph
Problem solved, I used the html2image Python module which converts the SVG (including embedded Emoji's) nicely to a PNG image an then use those images to create a MPG4 video using FFmpeg.

SkiaSharp support for color quantization for PNG files

I'm looking for an all-in-one solution for processing web images
Resizing
Cropping
Save as WEBP / JPEG / PNG
Drawing simple rectangles
Adding text
Reducing colors (quantization) for PNG
The only thing I'm not clear about is PNG quantization. Currently I'm using pngquant which works great, but I'd prefer to do everything in one place.
I see the SkiaSharp has SKImage.Encode() which takes a quality parameter. However there's no explanation as to what it actually is. Will this give me color quantization for PNG files? If not, is there something else in the library to do this?

How to get Numpy array of Canvas data?

I am building an application with Tkinter, where one is able to draw e.g. lines in a Canvas. This works well. However, I'm unable to find a method for getting the current Canvas data. Preferably I would like to get a numpy array out of the current Canvas data, since my post-processing steps are mostly using numpy.
Is there any way to build numpy arrays out of the Canvas data? In some color format like RGB, by preference?
I know that I can get the information e.g. of lines (like coordinates) out of the Canvas, but I do not need this information. I need a rasterized image data of the whole Canvas scene. Like a numpy array or a (rasterized) image (jpg, png, tiff, bitmap, ...).
Like #Bryan Oakley said: there is no way to get a rasterized version of a Tkinter Canvas drawing.
However, I figured out this workaround:
import skimage.io as ski_io
(...)
# draw your canvas
(...)
# save canvas to .eps (postscript) file
canvas.postscript(file="tmp_canvas.eps",
colormode="color",
width=CANVAS_WIDTH,
height=CANVAS_HEIGHT,
pagewidth=CANVAS_WIDTH-1,
pageheight=CANVAS_HEIGHT-1)
# read the postscript data
data = ski_io.imread("tmp_canvas.eps")
# write a rasterized png file
ski_io.imsave("canvas_image.png", data)
I do not really like workarounds, but skimage seems to be the fastest solution for reading postscript files and writing pngs.
Scikit-image is developed as a toolkit for SciPy, therefore it is working with scipy.ndimage internally, which is exactly what I want and can be used to create np.ndarray very easily.
Additionally scikit-learn is a powerful and fast image processing software itself, which can manipulate, read, and save various image formats.
Now you have the full choice: get a NumPy np.ndarray out of Canvas data for further computations, manipulate the scipy.ndimage with SciPy/scikit-image or save the data, e.g. as a rasterized png, to disk.

Extracting Text from a PDF file with embedded font

I have a PDF file containing some tabular data.
http://dl.dropbox.com/u/44235928/sample_rotate-0.pdf
I have to extract the tabular data from it. I have tried following with no success :
Select the text and paste it to notepad/excel-sheet. (I am getting junk characters)
Used save as text from Acrobat Reader. It is also giving junk characters and not the actual text.
Tried ApachePDFBox command line utility to extract text from PDF. It is also giving junk characters instead of real texts.
Finally I am trying a OCR solution. I am converting the pdf file into .tif images using ImageMagick and getting those images processed by tesseract OCR.
The OCR solution is not very accurate though( about 80% words matched ).
I tried changing density and geometry of the image created from PDF to get better results from tesseract OCR.
convert -rotate 90 -geometry 10000 -depth 8 -density 800 sample.pdf img_800_10000.tif;
tesseract img_800_10000.tif img_800_10000.tif nobatch letters;
I am not sure for what kind of image( density, geometry, monochromatic, sharpen boundary etc) would be best suited for the OCR.
Please suggest what could be the best possible parameters(density,geometry,depth etc) for generating images from a PDF file, so that the tesseract accuracy will increase.
I am open to other( non-ocr ) solutions as well.
In this case I recommend to NOT use ImageMagick for the PDF -> TIFF conversion. Instead, use Ghostscript. Two reasons:
Using Ghostscript directly will give you more control over individual parameters of the conversion.
ImageMagick cannot do that particular conversion itself -- it will call Ghostscript as its 'delegate' anyway, but will not allow you to give all the same fine-grained control that your own Ghostscript command will give you.
Most of the text in the table of your sample PDF is extremely small (I guess, only 4 or 5 pt high). This makes it rather difficult to run a successful OCR unless you increase the resolution considerably.
Ghostscript uses -r72 by default for image format output (such as TIFF). Tesseract works best with r=300 or r=400 -- but only for a font size from 10-12 pt or higher. Therefor, to compensate for the small text size you should make Ghostscript using a resolution of at least 1200 DPI when it renders the PDF to the image.
Also, you'll have to rotate the image so the text displays in the normal reading direction (not bottom -> top).
This is the command which I would try first:
gs \
-o sample.tif \
-sDEVICE=tiffg4 \
-r1200 \
-dAutoRotatePages=/PageByPage \
sample_rotate-0.pdf
You may need to play with variations of the -r1200 parameter (higher or lower) for best results.
Since a comment asked "How to define the geometry of an image when using Ghostscript as we do in convert?", here is an answer:
It does not make sense to define geometry (that is image dimensions) and resolution for a raster image created by Ghostscript at the same time.
Once you convert a vector based page of a given dimension (such as PDF) into a raster image (such as the TIFF G4 format) giving a desired resolution (as done in the other answer), you already indirectly and implicitly also did set the dimension:
The original PDF dimension of your sample file sample_rotate-0.pdf is 1008x612 points.
At a resolution of 72 DPI (the default Ghostscript uses if not given directly, or -r72 in the Ghostscript command if given directly) the image dimensions will be 1008x612 pixels.
At a resolution of 720 DPI (-r720 in the Ghostscript command) the image dimensions will be 10080x6120 pixels.
At a resolution of 1440 DPI (-r1440 in the Ghostscript command of my other answer) the image dimensions will be 20160x12240 pixels.
At a resolution of 1200 DPI (-r1200 in the Ghostscript command) the image dimensions will be 16800x10200 pixels.
At resolution of 1000 DPI (-r1000 in the Ghostscript command) the image dimensions will be 14000x8500 pixels.
At a resolution of 120 DPI (-r120 in the Ghostscript command) the image dimensions will be 1680x1020 pixels.
At resolution of 100 DPI (-r100 in the Ghostscript command) the image dimensions will be 1400x850 pixels.
If you absolutely insist to specify the dimension/geometry for the output image on the Ghostscript commandline (rather than the resolution), you can do so by adding -gNNNNxMMMM -dPDFFitPage to the commandline.
There you can find decoded content of your file: https://docs.google.com/open?id=0B1YEM-11PerqSHpnb1RQcnJ4cFk
A absolutely sure the OCR is the best way to read pdf file, but you can try REGEX-ing the native content. It going to be be the hard and long way.

Using reportlab to build PDF with vector-based graphs generated by matplotlib

I'm trying to build PDF-documents on the server-side in a Django-Installation using reportlab. These documents should contain several graphs which are to be created with matplotlib.
I already figured out how to make reportlab use matplotlib's images without dumping them to the filesystem temporarily by passing PIL-Image objects directly to the Image()-flowable. This works surprisingly well for rasterized images formats like PNG.
Now, the icing on the cake would be able to embed vector based graphics (like SVG).
I used svglib to convert SVGs generated by matplotlib to reportlab graphic objects but unfortunately svglib does omit the tickmarks and axis labels. On some graphs it fails in general.
Do you have any ideas?
This page has a solution that I haven't had a chance to test myself yet: https://web.archive.org/web/20120725125858/http://lateral.netmanagers.com.ar/weblog/posts/BB753.html
You can generate matplotlib graphics as pdf and use pdfrw to embed it in reportlab canvas as described in this answer

Resources