I wrote a Python script that fuses a stereo pair of images into an anaglyph image. When I view the image in a tkinter application I wrote the image looks good but when I save as a JPG and PNG to Photoshop it looks "confused". For a while I was wondering if I was crazy but I had my family look at the images and they agreed.
I figured the problem had something to do with the colors being screwed up and I figured I could prove it by making a simpler image so I made something that looks like a TV test pattern. Here's the smoking gun:
screenshot that shows the problem
On the left is the tkinter application showing the color bars, on the right I am viewing the image exported by the application, which I'm going to call A.PNG, in the Windows Photo Viewer.
The green is obviously different, and if I load the screenshot (B.PNG) into Photoshop I see the yellow bar on the left image is (180, 180, 16) which is what it supposed to be, but the photo viewer shows (176,178,41) for the yellow. If I use the eyedropper on A.PNG the yellow is (180, 180, 16) so the problem is that when the image gets loaded by other applications the color displayed is changed to something else.
I'm pretty sure this has something do with color management or gamma correction but I'm at a loss at what to do to my image so I can view it with other programs or print it out and have the colors look like they do in tkinter.
Here is the script that generates the color bars, writes them to a file and writes to a PNG
from math import floor
from tkinter import Tk, Label
from PIL.Image import new
from PIL import ImageDraw, ImageTk
_480p=(640,480)
WHITE75 = (180,180,180)
YELLOW75 = (180,180,16)
CYAN75= (16,180,180)
GREEN75= (16,180,16)
MAGENTA75 = (180,16,180)
RED75 = (180,16,16)
BLUE75 = (16,16,180)
BLACK75 = (16,16,16)
RAINBOW75 = [WHITE75, YELLOW75, CYAN75, GREEN75, MAGENTA75, RED75, BLUE75]
LOWER75 = [BLUE75, BLACK75, MAGENTA75, BLACK75, CYAN75, BLACK75, WHITE75]
GRAYS = [(16*i,16*i,16*i) for i in range(1,15)]
REDS = [(16*i,0,0) for i in reversed(range(1,15))]
GREENS = [(0,16*i,0) for i in range(1,15)]
BLUES = [(0,0,16*i) for i in reversed(range(1,15))]
class TestPattern():
def draw(self):
self.x = new("RGB",_480p,"black")
self.bars(RAINBOW75,0,320)
self.bars(LOWER75,320,360)
self.bars(GRAYS,360,420)
self.bars(REDS,420,440)
self.bars(GREENS,440,460)
self.bars(BLUES,460,480)
return self.x
def bars(self,colors,top,bottom):
draw = ImageDraw.Draw(self.x)
barwidth = 640 / len(colors)
for i in range(len(colors)):
draw.rectangle([floor(i*barwidth),top,floor((i+1)*barwidth),bottom], fill=colors[i])
root = Tk()
root.title("Image Loader")
root.geometry(f"640x480+300+150")
root.resizable(width=True, height=True)
pattern = TestPattern().draw()
pattern.save(r"D:\test-pattern.png")
tkimg = ImageTk.PhotoImage(pattern)
panel = Label(root, image=tkimg)
panel.image = tkimg
panel.grid(row=1, column=1)
root.mainloop()
curve=[23,37,51,66,80,96,111,126,142,158,174,190,206,222]