PIL(pillow)のインデックスカラーのあれこれ
PIL(pillow)のインデックスカラーのあれこれ
サンプルのJpegデータを読み込む
from PIL import Image, ImageDraw, ImageFont imo = Image.open('jpeg/IMG_2952x.jpg') print("mode = ",imo.mode) print("size = ",imo.size)
mode = RGB size = (640, 480)
jpeg画像フルカラーからパレットカラー(256色)に減色
im256 = imo.quantize() #減色 index color変換 print("mode = ",im256.mode) print("size = ",im256.size) im256.palette.save('palette.dat') im256
mode = P size = (640, 480)
Markdown記述だが、4スペースCODE識別の時は、後方のイメージが変換できなかったが
```
記述に変更したら、画像が読み込めるようになった。単純にBUGかな?
もちろん、256色モードがあるTIFFとGIFに変換もできる
im256.save('im256.tif') im256.save('im256.gif')
TIFFデータに変換したデータを読み込み、各データを見ていく PILライブラリのカラーパレットとTIFFのTAGに入っているパレットformatが違うので注意
from PIL import Image, ImageDraw, ImageFont im256_tiff = Image.open('im256.tif') im256_tiff print("mode = ",im256_tiff.mode) # P print("size = ",im256_tiff.size) # P print("getbands = ",im256_tiff.getbands()) # ('P',) print("getpixel(0,0) = ",im256_tiff.getpixel((0,0))) # 2 index 値 #print("getpalette = ",im256_tiff.getpalette()) # 2 index 値 palette = im256_tiff.getpalette() i=0 print("colorpalette[0]= (",palette[i*3+0],palette[i*3+1],palette[i*3+2],")") i=2 print("colorpalette[2]= (",palette[i*3+0],palette[i*3+1],palette[i*3+2],")") i=32 print("colorpalette[32]= (",palette[i*3+0],palette[i*3+1],palette[i*3+2],")") i=255 print("colorpalette[255]= (",palette[i*3+0],palette[i*3+1],palette[i*3+2],")") print("TAG data:") print("ImageWidth = " , im256_tiff.tag_v2[256]) # 8 print("ImageLength = " , im256_tiff.tag_v2[257]) # 8 print("BitsPerSample = " , im256_tiff.tag_v2[258]) # 8 # color map は、2 ** BitsPerSampleなので 256、RGB=3なので3*256データ # データ長はshortで16bit 0~65535、(0,0,0)~(65535,65535,65535) # しかし現在のRGBカラーは~(255,255,255)までで256で割らないと同じ値にならない # また、R0~R256,G0~G255,B0~B255の順に並んでいるのでgetpellteとは違うフォーマット print(type(im256_tiff.tag_v2[320][0]),len(im256_tiff.tag_v2[320])) # int tag_palette = im256_tiff.tag_v2[320] i=0 print("colorpalette[0]= (",tag_palette[0+i]/256,tag_palette[256+i]/256,tag_palette[512+i]/256,")") i=32 print("colorpalette[32]= (",tag_palette[0+i]/256,tag_palette[256+i]/256,tag_palette[512+i]/256,")") i=255 print("colorpalette[255]= (",tag_palette[0+i]/256,tag_palette[256+i]/256,tag_palette[512+i]/256,")")
mode = P
size = (640, 480)
getbands = ('P',)
getpixel(0,0) = 2
colorpalette[0]= ( 253 253 253 )
colorpalette[2]= ( 249 249 250 )
colorpalette[32]= ( 228 230 228 )
colorpalette[255]= ( 4 4 7 )
TAG data:
ImageWidth = 640
ImageLength = 480
BitsPerSample = (8,)
<class 'int'> 768
colorpalette[0]= ( 253.0 253.0 253.0 )
colorpalette[32]= ( 228.0 230.0 228.0 )
colorpalette[255]= ( 4.0 4.0 7.0 )
実際のパレットマップはこんな感じ
# -*- coding: utf-8 -*- from PIL import Image, ImageDraw, ImageFont def draw_pcolor_map(pcm): row,col,c_dx,c_dy,s_dx,y_osf = 32,8,16,16,16*8,24 im = Image.new("RGB", (col*(c_dx+s_dx), c_dy*row+y_osf),color=(255,255,255)) font_ttf = "C:/Windows/Fonts/msgothic.ttc" #MS ゴシック 他のOSの場合は適当にfont ファイルに変える draw = ImageDraw.Draw(im) draw.font = ImageFont.truetype(font_ttf, 24) # font size draw.text([0,0], "Index color map",(0,0,0)) draw.font = ImageFont.truetype(font_ttf, 14) # font size for x in range(0,col): for num in range(0,row): # color box ix = row*x+num pcolor = (pcm[ix*3],pcm[ix*3+1],pcm[ix*3+2]) draw.rectangle([(x*(c_dx+s_dx)+1,num*c_dy+1+y_osf), (x*(c_dx+s_dx)+c_dx-1,(num+1)*c_dy-1-1+y_osf)], outline=(0,0,0), fill=pcolor) # number str_color = '{0:>3}:({1:>3},{2:>3},{3:>3})'.format(ix,pcolor[0],pcolor[1],pcolor[2]) #print(str_color) # debug draw.text([x*(c_dx+s_dx)+c_dx+4,num*c_dy+y_osf], str_color,(0,0,0)) return im if __name__ == '__main__' : imo = Image.open('jpeg/IMG_2952x.jpg') im256 = imo.quantize() #減色 index color変換 pcm = im256.getpalette() im = draw_pcolor_map(pcm) im.show()
pcm = im256.getpalette() im = draw_pcolor_map(pcm) im