Converting Multi Page TIFF file doesn't respect resolution argument - python-imaging-library

I'm attempting to convert a multi page TIFF file into PDF using PIL but for some reason the DPI is always 300 despite me setting it otherwise. If the TIFF file is only one page it works but I can't seem to get it working for multi pages. Any idea where I am going wrong please?
from PIL import Image, ImageSequence
image = Image.open("test.tiff")
images = []
for i, page in enumerate(ImageSequence.Iterator(image)):
page = page.convert("RGB")
#page.
images.append(page)
if len(images) == 1:
images[0].save("test.pdf", resolution=600.0,optimize=True, quality=100)
else:
images[0].save("test.pdf", resolution=600.0,optimize=True, quality=100, save_all=True,append_images=images[1:])

Related

How to generate grayscale bitmap image using HEX data in XML on MacOS (Swift)

I have image source in XML format (the image size is variable therefore I will need to change the image placeholder size). The image source is individual pixel data written in HEX format as string. It is grayscale BMP image data (without header).
I would like to know how to work with the data in order to be able to convert the text HEX pixel data into an image to be displayed in MacOS app using Xcode and Swift.
I have achieved similar thing years back using Action Script for AIR app.
The image source can look like:
<Signature t="8209">000200010000000203435A4B03000000C8010205410....
So first thing is to convert the text HEX string into actual binary data, in Action Script I have used this code (part of cycle to read the whole known length of image data):
var pixelData:uint = parseInt(imgdata.substr((j-1)*2,2),16);
In this example, part of the "signature" XML key is also information about the actual image size, so I would like to be able to change the image size based on that data and be safe not to over/under run the byte stream length needed for the actual image.
So the whole looping through the image pixel data and constructing byte array with alpha, red, green, blue values looked like:
var bx2:ByteArray = new ByteArray();
if(img2_w!=0){
for (var j:Number = 0; j <imgdata.length / 2; j++)
{
var pixelData:uint = parseInt(imgdata.substr((j-1)*2,2),16);
bx2.writeByte(255);
bx2.writeByte(pixelData);
bx2.writeByte(pixelData);
bx2.writeByte(pixelData);
}
}
then it was about linking the byte array image data to the image itself:
var b_image1:ByteArray = new ByteArray();
var bmd_image1:BitmapData = new BitmapData(img1_w,img1_h, false, 0xFFCC00);
//getting the parsed XML data off selected item in the displayed grid - P6Grid
b_image1 = sigData[P6Grid.selectedIndex].sig1;
b_image1.position=0;
bmd_image1.setPixels(bmd_image1.rect,b_image1);
//reference to the visual component placed on the UI
img_sn1.source = bmd_image1;
Would anyone know how to do this using Swift and Xcode on MacOS app. Currently I am using sotory boards and figured out how to handle the file drop, check if that is XML document and parse the key values, so I can get to the XML data, but don't know how to turn them into the image.
Many thanks for your thoughts,
JendaDH

icon_path isn't working in win10toast module in python

I'm attempting a countdown clock in python 3.7 using win10toast, time and playsound. Here's the code:
import time
import playsound
import win10toast
Toaster = win10toast.ToastNotifier()
def countdown(y):
while y > 0:
print(y)
y -= 1
time.sleep(1)
playsound.playsound('alarm-clock-ringing.mp3')
Toaster.show_toast('Countdown notifier', 'countdown over', duration=9,
icon_path=r'D:\img.ico')
try:
x = int(input('how many seconds do you want to countdown?: '))
countdown(x)
except ValueError:
print('That wasn\'t an integer! Please enter an integer!')
It works fine, except for icon_path in line 14. The error I'm getting is:
ERROR:root:Some trouble with the icon (D:\img.ico): (0, 'LoadImage', 'No error message is available')
By the way, I'm using windows 10 pro 64-bit.
Thank you!
Hello!
import time
from win10toast import ToastNotifier
toaster = ToastNotifier()
toaster.show_toast("Hello World!!!","Python is 10 seconds awsm!",icon_path=
filename.ico,duration=10,threaded=False)
while toaster.notification_active():
time.sleep(0.1)
Copy and Paste,
Your Welcome :)
First, convert the .jpg or .png file that u have into a .ico file. U can do it using python's PIL library like this:
from PIL import Image
filename = "logo.png"
img = Image.open(filename)
img.save('logo.ico')
Now, u have saved the logo as an ico file, so u can easily use it in ur code like this:
from win10toast import ToastNotifier
toast = ToastNotifier()
file_name = 'logo.ico'
toast.show_toast("Notification","Notification Body", duration=5, icon_path = file_name)
Hope that this helps!
According to the documentation, LOAD-ICON should pick up the 32x32 version of the icon (if it exists)
LOAD-IMAGE does not work if .ICO file contains a 256x256 icon.
Using an ICO file with 32x32, 16x16, and/or 48x48 icons works.
Icon files with several images work unless it contains a 256x256 version. In this case, no icon is loaded.
for reference click here
just replace this:
'D:\img.ico' ==> 'D:/img.ico'
or use it in this way:
'D:\\img.ico'
Try using a .ico file, that would probably work..

Remove PdfImageOject from a PDF

I have 1000th of PDF generated from emails containing .png (I am not owner of the generator). For some reasons, those PDF are very very slow to render with the Imaging system I am using (I am not the developer of that system and may not change it).
If I use iTextSharp and implement a IRenderListener to count the Images to be rendered, there are thousands per page (99% being 1 or 2 pixels only). But if I count the Images in the resources of the PDF, there are only a few (~tens).
I am counting the images in the resources, per page, with the code here after
var dict = pdfReader.GetPageN(currentPage)
PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(dict.Get(PdfName.RESOURCES));
PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));
if (xobj != null)
{
foreach (PdfName name in xobj.Keys)
{
PdfObject obj = xobj.Get(name);
if ((obj.IsIndirect()))
{
PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);
PdfName subtype = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));
if (PdfName.IMAGE.Equals(subtype))
{
Count++
And my IRenderListener looks like this:
class ImageRenderListener : IRenderListener
{
public void RenderImage(iTextSharp.text.pdf.parser.ImageRenderInfo renderInfo)
{
PdfImageObject image = renderInfo.GetImage();
if (image == null) return;
var refObj = renderInfo.GetRef();
if (refObj == null)
Count++; // but why no ref ??
else
Count++;
}
I just started to learn about PDF specification and iTextSharp this evening, to analyze my PDF and understand what could be wrong... if I am correct, I see that many images to be rendered that are not referencing a resource (refObj == null) and that they are .png (image.streamContentType.FileExtension = "png"). So, I think those are the images making the rendering so slow...
For testing purpose, I would like to delete those images from the PDF but don't find how to proceed.
I only found code samples to remove image that are in the resources... but the images I want to delete are not :/
Is there any code sample somewhere to help me ? I did google on "iTextSharp remove object", etc... but there was nothing similar to my case :(
Let me start with the blunt observation that you have a shitty PDF.
The image you see when opening the PDF in a PDF viewer seems to be composed of several small 1- or 2-pixel images. The drawing operations to show these pixels one by one is suboptimal, no matter which imaging system you use: you are faced with a bad PDF.
In your first snippet, I see that you loop over all of the indirect objects stored in the the XObject resources of each page in search of images. You count these images, resulting in a number of Image XObjects stored in the PDF. If you add up all the Count values for all the pages, this number can be higher than the actual number of Image XObject stored in the PDF as you don't take into account that some images can be reused on different pages.
You do not count the inline images that are stored in the content streams. I'm biased. In the ISO committees for PDF, I'm on the side of the group of people saying that "inline images are evil" and "inline images should die". For now, we didn't succeed in getting rid of inline images, but we introduced some substantial limitations that should reduce the (ab)use of inline images in PDF that conform to ISO-32000-2 (the PDF 2.0 spec that is due in 2016).
You've already discovered that your PDF has inline images. Those are the images where refObj == null. They are not stored as indirect objects; they are stored inline, in the content stream of the page. As you can imagine based on my feelings towards inline images, I consider your PDF being a bad PDF for this reason (although it does conform to ISO-32000-1).
The presence of inline images is a first explanation why you have a different image count: when you loop over the indirect objects you only find part of the images. When you parse the document for images, you also find the inline images.
A second explanation could be the fact that the Image XObject are used more than once. That's the whole point of not using inline images. For instance: if you have an image that represents a logo that needs to be repeated on every page, one could use inline images. That would be a bad idea: the same image bytes would be present in the PDF as many times as there are pages. One should use an Image XObject. In this case, the image bytes of the logo are stored only once in an indirect object. There's a reference to this object from every page, so that the image bytes are stored in the document only once. In a 10-page document, you can see 10 identical images on 10 pages, but when looking inside the document, you'll find only one image that is referenced from every page.
If you remove Image XObjects by removing the indirect objects containing the image stream objects, you have to be very careful: are you sure you're not corrupting your document? Because there's a reference to the Image XObject in the content stream of your page. This reference points to an entry in the /XObjects entry of the page's /Resources. This /XObject references to the stream object with the image bytes. If you remove that indirect object without removing the references (e.g. from the content stream), you break your PDF. Some viewers will ignore those errors, but at some point in time some tool (or some body) is going to complain that your PDF is corrupt.
If you want to remove inline images, you have to parse all the content streams in your PDF: page content streams as well as Form XObject content streams. You have to rewrite all these streams and make sure all inline images are removed. That is: all objects that that start with the BI operator (Begin Image) and end with the EI operator (End Image).
That's a task for a PDF specialist who knows both iTextSharp and ISO-32000-1 inside-out. The solution to your problem probably doesn't fit into an answering window on StackOverflow.
I'm the original author of iText. From a certain point of view, iText is like a sharp knife. A sharp knife is a very good tool that can be used for many good things. However, you can also seriously cut your fingers when you're not using the knife in a correct way. I hope you'll be careful and that you're not going to create a whole series of damaged PDF files.
For instance: you assume that some of the files in the PDF are PNGs because iText suggests to store them as PNGs. However: PNG is not supported by ISO-32000-1, so your assumption that your PDF contains PNGs is wrong. I honestly worry when I see questions like yours.

three.js toDataURL PNG is black

I'm trying to grab a screenshot with renderer.domElement.toDataURL("image/png"), and save it to a file.
The image is the right size, but it's black.
I have preserveDrawingBuffer turned on.
I think I'm decoding and saving the file correctly, because when I hexdump it I can see the correct initial characters for the PNG format, as well as the IHDR and IDAT chunk headers. However the closing IEND is missing.
Any known issues here? Hints? Windows 7/Firefox up to date if it matters.
Thanks... (Sorry if this is dumb, I'm very new to three.js)
I had somewhat similar problems with Windows 7/Firefox. PNG Data URL's would be randomly truncated or something, much shorter than a successful PNG export. Trying to set that data url as image src resulted in "Image corrupt" exception or something in FF. As little sense it makse, setting a small window.setTimeout (10ms) between rendering and getting the data URL helped in my case. Maybe Firefox needs a rest from the JS engine before it refreshes some canvas internal state or something.. weird.
I switched to JPG format (smaller files => truncation less of an issue?) and still saw it not working, then I tried this tip which I found here
If you want to save data that is derived from a Javascript
canvas.toDataURL() function, you have to convert blanks into plusses.
If you do not do that, the decoded data is corrupted:
<?php
$encodedData = str_replace(' ','+',$encodedData);
$decodedData = base64_decode($encodedData);
?>
This worked. Thanks, Mekal.
This tip seems to apply to JPGs only. I saw PNGs decoding correctly without the + replacement, and corruptly with it. I can use JPGs so my personal problem is solved. However I never saw a PNG that wasn't black even when decoded correctly and not truncated.
Kind of a lousy situation either way, I feel like. What is up with the +'s?
A black texture is a sign that you did not indicate the texture needs to be updated.
Also, you do not need to use canvas.toDataURL(). You can pass in the canvas reference to the THREE.Texture object.
var canvas = document.getElementById('#myCanvas');
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
// Now render the scene

PIL to Qimage conversion: QImage constructor does not free memory

I am developping a Qt application loading pictures with PIL, modifying colors and alpha channels, then converting them as QImage.
Here is the problematic piece of code: normal repeated usage of the ImageQt function: # memory is filled around 7 mB/s
if name == 'main':
while True:
im = Image.open('einstein.png') #small picture
imQt = QtGui.QImage(ImageQt.ImageQt(im)) # convert to PySide.QtGui.QImage
imQt.save('outtest.png')# -> rendered picture is correct
#del(imQt) and del(im) does not change anything
time.sleep(0.02)
The problem here is the crazy memory filling, when the picture is supposed to be erased by the garbage collector. I checked with gc.collect(), but it did not change anything.
This example shows what happends with the imageQt function, but in fact, I noticed this is a problem caused by QImage: if you repeatedly use the QImage constructor with data, the memory used by python process increases: im= Image.load('mypic.png').convert('RGBA')
data = im.toString('raw','RGBA')
qIm = QtGui.QImage(data,im.size[0],im.size[1],QtGui.QImage.Format_ARGB32)
qIm.save('myConvertedPic.png')# -> picture is perfect
If you put this code in a loop, memory will increase, as 1st example. From there i am a bit lost because this is a PySide problem...
I tried to use a workaround, but it does not work either:
#Workaround, but not working ....
if name == 'main':
while True:
im = Image.open('einstein.png') #small picture
imRGBA = im.convert('RGBA') # convert to RGBA
imRGBA.save('convtest.png') # ->picture is looks perfect
imBytes = imRGBA.tostring('raw','RGBA')
#print("size %d %d" % (imRGBA.size[0],imRGBA.size[1]))
qImage = QtGui.QImage(imRGBA.size[0],imRGBA.size[1],QtGui.QImage.Format_ARGB32) # create new empty picture
qImage.fill(QtCore.Qt.blue) # fill with blue, otherwise it catches pieces of the picture still in memory
loaded = qImage.loadFromData(imBytes,'RGBA') # load from raw data
print("success %d" % loaded)# -> returns 0
qImage.save('outtest.png')# -> rendered picture is blue
time.sleep(0.02)
I am really stuck here, if you could help find a solution with this workaround ? Because I'm really stuck here!
Also I would like to discuss the QImage problem. Is there any reliable way to free this memory ? Could the fact I am using python3.2(32bits) be a problem in this case ? Am I the only one in this case ?
The imports I am using in case of:
import time
import sys
import PySide
sys.modules['PyQt4'] = PySide # this little hack allows to solve naming problem when using PIL with Pyside (instead of PyQt4)
from PIL import Image, ImageQt
from PySide import QtCore,QtGui
After further unsuccessful searching, I noticed, that the PIL function image.tostring() associated with a QImage constructor caused this problem
im = Image.open('einstein.png').convert('RGBA')
data = im.tostring('raw','RGBA') # the tostring() function is out of the loop
while True:
imQt = QtGui.QImage(data,im.size[0],im.size[1],QtGui.QImage.Format_ARGB32)
#imQt.save("testpic.png") #image is valid
time.sleep(0.01)
#no memory problem !I think I am really close to find what is wrong, but I cannot point it out.
It definitely has something to do with the data variable being held in memory.