## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
emptixo
thanks m8
Andrew Shay
@Andrew-Shay

Hello. I am creating a "dial", like on a speedometer. I am trying to rotate the dial, but it doesn't seem like it's rotating correctly. I am trying to rotate it on the bottom middle point like a speedometer. The output looks like expand=True is not fully expanding

im = Image.open("needle.png")
width = im.width
height = im.height
x = width / 2
y = height
loc = (x, y)
im.rotate(45, center=loc, expand=True).show()

Any thoughts?

Andrew Shay
@Andrew-Shay
And the needle image is just the needle itself. No extra pixels around the needle or anything
Andrew Murray

Investigating, I find http://pillow.readthedocs.io/en/5.1.x/reference/Image.html?highlight=rotate#PIL.Image.Image.rotate - 'Note that the expand flag assumes rotation around the center and no translation.'

It's entirely possible you'll figure out your own solution to this problem now, but to be helpful, my suggestion would be to manually make the image larger first, so that you don't need to worry about automatic expanding -

from PIL import Image
im = Image.open("needle.png")
width = im.width
height = im.height

expandedIm = Image.new(im.mode, (im.height*2, im.height))
pasteX = int(height-width/2)
pasteY = 0
expandedIm.paste(im, (pasteX, pasteY))

x = width / 2
y = height
loc = (x+pasteX, y+pasteY)
expandedIm.rotate(45, center=loc).show()

Andrew Shay
@Andrew-Shay
Ah, that note is the key. I did find a solution. I took the full gauge image, removed the gauge and left just the needle and overlayed it after transformation
Zaki Shaheen
@zakishaheen
Is there a built-in functionality to map a grayscale image to a colored one given a lookup table for grayscale=>rgb values? I can't figure out how to do this. Right now I convert the input png to grayscale using the L convert, then convert it into an numpy array and make a numpy lookup table - and use numpy to do the conversion.
Andrew Murray

Well, the basic way to do that would be using pixel access - https://pillow.readthedocs.io/en/3.0.x/reference/PixelAccess.html

from PIL import Image

# This is just a quick RGB image that looks grayscale

out = Image.new('RGB', im.size)
for x in range(0, im.width):
for y in range(0, im.height):
r, g, b = px_in[x, y]
px_out[x, y] = (r, int(g / 2), int(b / 4))
out.save('out.png')

Alexander Karpinsky
@homm
@zakishaheen Just use the point method three times to generate thee grayscale images for R G B channels , then merge them together
Zaki Shaheen
@zakishaheen
@radarhere awesome. Thanks. Do you think it would be faster than numpy based pixel manipulation?
Zaki Shaheen
@zakishaheen
@radarhere also it seems like 3DLUT is not available on v5.1 ... do you know when it will graduate out of master?
Zaki Shaheen
@zakishaheen
@homm do you know when will 3DLut imagefilter be in a released version? seems like pillow-lut-tools needs it but i can't use it till its in a released version
oh - got it. The release date is set to 7/1
Looking forward.
Andrew Murray
I don’t know which method would be faster - I doubt that it would be pixel access though, as the docs that it is ‘fairly slow’
Zaki Shaheen
@zakishaheen
@radarhere 3DLUT is mind-blowing fast. So basically for my usecase, it is 55X faster than getpixel etc. and 15X faster than numpy based approach I was using.
can't wait for it to get released in 5.2 :)
@homm great work on pillow-lut-tools. Have a few ideas to improve the file loading/etc. I'll try to do a pull-request soon when I get time.
Alexander Karpinsky
@homm
Thanks ) I still think that the point method could be fister for your case, because you don't nedd 3D LUT, you only need three 1D LUT, which "point" is.
Zaki Shaheen
@zakishaheen
@homm actually, 3DLUT works because in my pipeline, its easier for artist to export a .cube file from photoshop at 'low' quality and then I just call that function. The artist then has the flexibility. We're essentially taking a grayscale image and passing it thru different .cube files to get a rendered image (think drawing a grayscale body and having a .cube file for the different skin tones - can shade a cartoon asset in different skin tones).
Alex Clark
@aclark4life
Yay people using gitter
Konstantin Kopachev
@kkopachev
@homm could you clarify how RGBX rawmode read helps with performance in jpeg decoder? python-pillow/Pillow#1989
Isn't it end up shuffling same way to RGB? RGB->RGB and RGBX->RGB unpackers are same, so how speedup is achieved?
internetfan420
@internetfan420
anyone around that could help with writing the whole of a text file instead of just a string
Andrew Murray

Hi. I don't quite understand your question. However, I will attempt to answer.

To read an entire file in Python -

with open('in.txt', 'r') as f:

To write that data back to a file -

with open('out.txt', 'w') as f:
f.write(data)

If you are having trouble because your data is bytes, not a string -

with open('out.txt', 'wb') as f:
f.write(data)

Also, if your question relates to Pillow in some way, please explain further, because I don't see it.

Zaki Shaheen
@zakishaheen
@homm in my production system, pillow-lut gets built as a wheel. I want to be able to bring in the tests too....do you have plans to incldue that in setup.py setup.cfg?
Alexander Karpinsky
@homm
@kkopachev Internally in Pillow RGB and RGBX are the same modes. But for libjpeg RGB is true RGB, where each pixel consists of 3 bytes. So RGB (libjpeg) → RGB (Pillow) convertion is costly operation, while RGBX (libjpeg) → RGB (Pillow) is just copying.
@zakishaheen Sorry, I don't understend what do you want. setup.cfg is automaticaly generated, I even never open it and don't know what it contains )
VisualCoder
@VisualTuber_gitlab
hello, is this a place where i can ask for help about an issue i'm having with pillow?
Andrew Murray
VisualCoder
@VisualTuber_gitlab
yes and it has been resolved
kurwazavr
@kurwazavr
hello everyone
is there a way one can map one image over other by uv map?
that is, I have a uv map, and I transform a given image according to it
Andrew Murray

When you say UV map, you’re talking about Blender, yes? Are you sure this is a Pillow question, and not a Blender question?

A bit of Googling, and https://blender.stackexchange.com/questions/7855/how-can-i-set-the-image-to-use-the-uv-map-using-the-python-api seems interesting.

James Albert
@jamesalbert
Has anybody had the problem, when taking multiple cropped frames from a transparent png in order to save them as a gif, that the previous frames get tacked onto future ones?
currently getting this ^, I can post code if needed, but I .show() each frame and none of them show this blend of frames.
But my save looks like: snaps[0].save('build/sprite.gif', transparency=0, save_all=True, append_images=snaps[1:], loop=0)
Andrew Murray
There are similar issues when starting with GIF images, but I’m surprised that you’re experiencing this starting with a PNG. The original image would be most helpful if you’d like this looked at a bit more.
James Albert
@jamesalbert
Yeah np, got it right here
as for the code, I'm just iterating over a list of quadrants, cropping them, then saving them. I'll get a snippet going here in a sec...
James Albert
@jamesalbert
snaps = list()
crop = image.crop(q)
alpha = crop.getchannel('A')
mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0)
crop.info['transparency'] = 255
snaps.append(crop)
snaps[0].save('build/sprite.gif', transparency=0, save_all=True, append_images=snaps[1:], loop=0)
there we go (more or less), I've been experimenting with a couple different ways, none of which have worked
James Albert
@jamesalbert

I also played around with:

bg = Image.new('RGBA', crop.size, (255, 255, 255, 255))
bg.paste(crop, alpha)
crop = bg.convert('RGB').convert('P', palette=Image.ADAPTIVE)

but same issue

Andrew Murray
Okay, I was able to get your code working using ‘disposal’
from PIL import Image
image = Image.open('walking-sprite.png')
snaps = []
for i in range(0, 8):
crop = image.crop((i * 28, 111-28, (i+1)*28, 111))
alpha = crop.getchannel('A')
mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0)
snaps[0].save('sprite.gif', transparency=0, save_all=True, append_images=snaps[1:], loop=0, disposal=2)
Hello there! I'd like to add a function to Image (or some other place?) to automatically rotate an image according to it's EXIF Orientation tag, and remove that tag thereafter. Do you have interest in this?