how to mix 100+ pictures with python pillow - python

Now I'm trying to mix 100+ pictures to one pic(like .png) with pillow(fork PIL)
And I know "PIL.Image.blend(im1, im2, alpha)" can fix all pictures ,however the picture's color was too light.
I want to fix the 100+ pictures with the color, not the transparency(alpha).
I know another API for fix is "PIL.Image.composite(image1, image2, mask)"
but when using it, it tell something was wrong.
"im = Image.composite(p, im, "RGBA")" # Am I using right?
p and im was two open Image object open by API "PIL.Image.open(fp, mode='r')"
File "GA_engine.py", line 187, in test_create
im = Image.composite(p, im, "RGBA")
File "/Library/Python/2.7/site-packages/PIL/Image.py", line 2313, in composite
image.paste(image1, None, mask)
File "/Library/Python/2.7/site-packages/PIL/Image.py", line 1313, in paste
mask.load()
AttributeError: 'str' object has no attribute 'load'

It's very unclear what you mean by "fix" the images, but it looks like you're trying to combine them in some way. I can't say if you're using the right tool, since I don't know what you're trying to accomplish, but I can say that you're not using the tool correctly:
If you read the docs for Pillow, you'll see that Image.composite requires, as the third argument, another image to use as a transparency mask.
So in place of "RGBA", you need to supply another Image object of the same size as the other two. Does that answer your question?

Related

access XML Content <a14:sharpenSoften> for image Blur using Python Docx

I am planning to search the specific heading in the document, and then i have to strike out all the contents in that heading. The document has many headings, each heading may have paragraph, tables, images altogether or in any combinations.
I have installed docx, i was able to search the specific heading, strike out paragraph, tables.
Now next task to the access the images under that Heading and blur those images (instead of strikeout, we are planning to blur the image)
I am able to get the resource id for the images which is under Specific Heading by using the code in the link Bluring the Image which is under specific Heading using Python docx
Since there are no direct API supporting this features, I am trying to use the XML code as referenced in https://github.com/python-openxml/python-docx/issues/55#issuecomment-43914055..
I am having the XML Code without blur and with blur (by manually setting the Artistic Effect (for blur) of Image)
XML Code for the Image without blur:
<pic:blipFill>
<a:blip r:embed="rId11">
<a:extLst>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
</a:ext>
</a:extLst>
</a:blip>
<a:srcRect/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>`
XML Code for the image with blur:
<pic:blipFill>
<a:blip r:embed="rId11">
<a:extLst>
<a:ext uri="{BEBA8EAE-BF5A-486C-A8C5-ECC9F3942E4B}">
<a14:imgProps xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main">
<a14:imgLayer r:embed="rId12">
<a14:imgEffect>
<a14:sharpenSoften amount="-50000"/>
</a14:imgEffect>
</a14:imgLayer>
</a14:imgProps>
</a:ext>
<a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
<a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" val="0"/>
</a:ext>
</a:extLst>
</a:blip>
<a:srcRect/>
<a:stretch>
<a:fillRect/>
</a:stretch>
</pic:blipFill>
From the above codes with and without blur, it is clear that the following code is the only difference between them
<a14:imgProps xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main">
<a14:imgLayer r:embed="rId12">
<a14:imgEffect>
<a14:sharpenSoften amount="-50000"/>
</a14:imgEffect>
</a14:imgLayer>
</a14:imgProps>
I am able to access the tag till "a:ext", see below code
trans = r.xpath('.//w:drawing/wp:inline/a:graphic/a:graphicData/'
'pic:pic/pic:blipFill/a:blip/a:extLst/a:ext')
and trans is returning the parameter
<CT_PositiveSize2D '<a:ext>' at 0x4535db8>
If i am trying to access the next level tag "a14:imgProps" after "a:ext", it is throwing the following error
File "C:\Python27\Lib\site-packages\docx\oxml\xmlchemy.py", line 751, in xpath
xpath_str, namespaces=nsmap
File "src\lxml\etree.pyx", line 1589, in lxml.etree._Element.xpath (src\lxml\etree.c:61221)
File "src\lxml\xpath.pxi", line 307, in lxml.etree.XPathElementEvaluator.call (src\lxml\etree.c:178760)
File "src\lxml\xpath.pxi", line 227, in lxml.etree._XPathEvaluatorBase._handle_result (src\lxml\etree.c:177712)
XPathEvalError: Undefined namespace prefix
Since i thought accessing the parameter "a14:sharpenSoften" will be helpful to blur the image. But i dont know how to access this parameter.
Can any one help me to access the parameter "a14:sharpenSoften" OR if there is any other method to blur the image which is under specific heading, paragraph or tables, let me know about it.
Note: I am using Python docx module and Python 2.7
You can overcome this error by adding the following lines before calling r.xpath():
import docx
docx.oxml.ns.nsmap['a:14'] = "http://schemas.microsoft.com/office/drawing/2010/main"
Then this code will allow you to set the a14:sharpenSoften attribute:
xpath_str = (
'.//w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill'
'/a:blip/a:extLst/a:ext/a14:imgProps/a14:imgLayer/a14:imgEffect/a14:'
'sharpenSoften'
)
sharpenSoftens = r.xpath(xpath_str)
if not sharpenSoftens: # then that element is not found
return
sharpenSoften = sharpenSoftens[0]
sharpenSoften.set('amount', '-50000')

Overlaying coloured pixels on top of an image using Python Imaging Library

Okay, first thing first. This is a near duplicate of this question.
However, the issue I am facing is slightly different in a critical way.
In my application, I read a generic file name in, load said image, and display it. Where it gets tricky is I have overlay the appearance of being 'highlighted'. To do this, I was using the Image.blend() function, and blending it with a straight yellow image.
However, when dealing with blend, I was fighting the error that the two images are not compatible to be blended. To solve this, I opened the sample image I had in paint, and just pasted yellow over the whole thing, and saved it as a copy.
It just occurred to me that this will fail when a different type of image is read in by file name. Remember this needs to be generic.
So my question is: Instead of making a copy of the image manually, can I get python to generate one by copying the image and modifying it so it is solid yellow? Note: I do not need to save it after, so just making it happen is enough.
Unfortunately, I am not allowed to share my code, but hopefully the following will give an idea of what I need:
from PIL import Image
desiredWidth = 800
desiredHeight = 600
primaryImage = Image.open("first.jpg").resize((desiredWidth, desiredHeight), Image.ANTIALIAS)
# This is the thing I need fixed:
highlightImage = Image.open("highlight.jpg").resize((desiredWidth, desiredHeight), Image.ANTIALIAS)
toDisplay = Image.blend(primaryImage, highlightImage, 0.3)
Thanks to anyone who can help.
Sounds like you want to make a new image:
fill_color = (255,255,0) #define the colour as (R,G,B) tuple
highlightImage = Image.new(primaryImage.mode, #same mode as the primary
primaryImage.size, #same size as the primary
fill_color)#and the colour defined above
this creates a new image with the same mode and size as the already opened image, but with a solid colour. Cheers.
Also if you are using Pillow instead of original PIL you can even get the color by name:
from PIL.ImageColor import getcolor
overlay = 'yellow'
fill_color = getcolor(overlay, primaryImage.mode)

Reading an image into pygame with incorrect file extension

I want to load a JPS file into pygame. A JPS file is simply a jpeg file with the image consisting of two side by side stereo pictures. While Pigame will load it in if I change the extension to jpg and use pygame.image.load(file_name), what I want to do is to load the file into memory and then tell Pigame to load the file in from a buffer and that the buffer contains a jpeg file.
I would like to do it this way because later I want to extend things so that I can load in an MPO file which is a file that contains two jpeg files and I suspect that the same techniques will be involved.
I have tried the pygame.image.frombuffer and pygame.image.fromstring but get the error message that the "String length does not equal format and resolution size". I think this is because I am not telling it that the buffer contains a jpeg.
Any one have any idea how this can be done?
Perhaps something along these lines (untested):
with open('image.jps', 'rb') as imgfile:
imgbuf = StringIO(imgfile.read())
image1 = pygame.image.load(imgbuf)
Since you say it works, you could probably shorten things as shown below since there's no reason to give the image buffer a name and keep it around:
with open('image.jps', 'rb') as imgfile:
image1 = pygame.image.load(StringIO(imgfile.read()))

PIL "IOError: image file truncated" with big images

I think this problem is not Zope-related. Nonetheless I'll explain what I'm trying to do:
I'm using a PUT_factory in Zope to upload images to the ZODB per FTP. The uploaded image is saved as a Zope Image inside a newly created container object. This works fine, but I want to resize the image if it exceeds a certain size (width and height). So I'm using the thumbnail function of PIL to resize them i.e. to 200x200. This works fine as long as the uploaded images are relatively small. I didn't check out the exact limit, but 976x1296px is still ok.
With bigger pictures I get:
Module PIL.Image, line 1559, in thumbnail
Module PIL.ImageFile, line 201, in load
IOError: image file is truncated (nn bytes not processed).
I tested a lot of jpegs from my camera. I don't think they are all truncated.
Here is my code:
if img and img.meta_type == 'Image':
pilImg = PIL.Image.open( StringIO(str(img.data)) )
elif imgData:
pilImg = PIL.Image.open( StringIO(imgData) )
pilImg.thumbnail((width, height), PIL.Image.ANTIALIAS)
As I'm using a PUT_factory, I don't have a file object, I'm using either the raw data from the factory or a previously created (Zope) Image object.
I've heard that PIL handles image data differently when a certain size is exceeded, but I don't know how to adjust my code. Or is it related to PIL's lazy loading?
I'm a little late to reply here, but I ran into a similar problem and I wanted to share my solution. First, here's a pretty typical stack trace for this problem:
Traceback (most recent call last):
...
File ..., line 2064, in ...
im.thumbnail(DEFAULT_THUMBNAIL_SIZE, Image.ANTIALIAS)
File "/Library/Python/2.7/site-packages/PIL/Image.py", line 1572, in thumbnail
self.load()
File "/Library/Python/2.7/site-packages/PIL/ImageFile.py", line 220, in load
raise IOError("image file is truncated (%d bytes not processed)" % len(b))
IOError: image file is truncated (57 bytes not processed)
If we look around line 220 (in your case line 201—perhaps you are running a slightly different version), we see that PIL is reading in blocks of the file and that it expects that the blocks are going to be of a certain size. It turns out that you can ask PIL to be tolerant of files that are truncated (missing some file from the block) by changing a setting.
Somewhere before your code block, simply add the following:
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
...and you should be good.
EDIT: It looks like this helps for the version of PIL bundled with Pillow ("pip install pillow"), but may not work for default installations of PIL
Here is what I did:
Edit LOAD_TRUNCATED_IMAGES = False line from /usr/lib/python3/dist-packages/PIL/ImageFile.py:40 to LOAD_TRUNCATED_IMAGES = True.
Editing the file requires root access though.
I encountered this error while running some pytorch which was maybe using the PIL library.
Do this fix only if you encounter this error, without directly using PIL.
Else please do
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
Best thing is that you can:
if img and img.meta_type == 'Image':
pilImg = PIL.Image.open( StringIO(str(img.data)) )
elif imgData:
pilImg = PIL.Image.open( StringIO(imgData) )
try:
pilImg.load()
except IOError:
pass # You can always log it to logger
pilImg.thumbnail((width, height), PIL.Image.ANTIALIAS)
As dumb as it seems - it will work like a miracle. If your image has missing data, it will be filled with gray (check the bottom of your image).
Note: usage of camel case in Python is discouraged and is used only in class names.
This might not be a PIL issue. It might be related to your HTTP Server setting. HTTP servers put a limit on the size of the entity body that will be accepted.
For eg, in Apache FCGI, the option FcgidMaxRequestLen determines the maximum size of file that can be uploaded.
Check that for your server - it might be the one that is limiting the upload size.
I was trapped with the same problem. However, setting ImageFile.LOAD_TRUNCATED_IMAGES = True is not suitable in my case, and I have checked that all my image files were unbroken, but big.
I read the images using cv2, and then converted it to PIL.Image to get round the problem.
img = cv2.imread(imgfile, cv2.IMREAD_GRAYSCALE)
img = Image.fromarray(img)
I had to change the tds version to 7.2 to prevent this from happening. Also works with tds version 8.0, however I had some other issues with 8.0.
When image was partly broken, OSError will be caused.
I use below code for check and save the wrong image list.
try:
img = Image.open(file_path)
img.load()
## do the work with the loaded image
except OSError as error:
print(f"{error} ({file_path})")
with open("./error_file_list.txt", "a") as error_log:
log.write(str(file_path))

'cannot filter palette images' error when doing a ImageEnhance.Sharpness()

I have a GIF image file. I opened it using PIL.Image and did a couple of size transforms on it. Then I tried to use ImageSharpness.Enhance() on it...
sharpener = PIL.ImageEnhance.Sharpness(img)
sharpened = sharpener.enhance(2.0)
This is causing an exception:
<type 'exceptions.ValueError'>
('cannot filter palette images',)
I tried to google for this error, but did not find anything. Can someone help me figure out what is going wrong?
FYI the mode of the input image is 'P'. I don't have this problem if I work with jpg images.
sharpener = PIL.ImageEnhance.Sharpness (img.convert('RGB'))
It's quite common for algorithms to be unable to work with a palette based image. The convert in the above changes it to have a full RGB value at each pixel location.

Categories