home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 October / maximum-cd-2011-10.iso / DiscContents / digsby_setup.exe / lib / gui / toolbox / imagefx.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-06-22  |  17.1 KB  |  465 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. DISABLE_ALL_CACHING = False
  5. NUM_IMAGES_TO_CACHE = 80
  6. import wx
  7. from wx import ImageFromDataWithAlpha, BitmapFromImage, BitmapFromIcon, ImageFromBitmap, IMAGE_QUALITY_HIGH, Point
  8. from PIL import Image, ImageFilter, ImageMath, ImageOps, ImageEnhance
  9. from PIL.Image import BICUBIC, ANTIALIAS
  10. from functools import wraps
  11. from uuid import uuid1
  12. _imagecache = None
  13.  
  14. def _get_imagecache():
  15.     global _imagecache
  16.     if _imagecache is None:
  17.         LRU = LRU
  18.         import util.lrucache
  19.         _imagecache = LRU(NUM_IMAGES_TO_CACHE)
  20.     
  21.     return _imagecache
  22.  
  23.  
  24. def cachesize():
  25.     return sum((lambda .0: for img in .0:
  26. img.DecodedSize)(_get_imagecache.values()))
  27.  
  28. CORNERS = (('tl', None), ('tr', Image.ROTATE_270), ('bl', Image.FLIP_TOP_BOTTOM), ('br', Image.ROTATE_180))
  29.  
  30. def cacheing(func):
  31.     name = func.__name__
  32.     
  33.     def wrapper(img, *a):
  34.         
  35.         try:
  36.             cachekey = img.cachekey
  37.         except AttributeError:
  38.             
  39.             try:
  40.                 cachekey = (img.path,)
  41.             except AttributeError:
  42.                 img.path = str(uuid1())
  43.                 cachekey = (img.path,)
  44.             except:
  45.                 None<EXCEPTION MATCH>AttributeError
  46.             
  47.  
  48.             None<EXCEPTION MATCH>AttributeError
  49.  
  50.         key = cachekey + (name + repr(a),)
  51.         imagecache = _get_imagecache()
  52.         
  53.         try:
  54.             return imagecache[key]
  55.         except KeyError:
  56.             img = func(img, *a)
  57.             img.cachekey = key
  58.             imagecache[key] = img
  59.             return img
  60.  
  61.  
  62.     wrapper = (None, wraps(func))(wrapper)
  63.     wrapper.nocache = func
  64.     return wrapper
  65.  
  66. if DISABLE_ALL_CACHING:
  67.     import sys
  68.     print >>sys.stderr, 'WARNING: image caching is disabled'
  69.     objmemoize = refmemoize = cacheing = (lambda f: f)
  70. else:
  71.     refmemoize = objmemoize = cacheing
  72.  
  73. def wxbitmap_to_wximage(wxbitmap):
  74.     return wxbitmap.ConvertToImage()
  75.  
  76. wxbitmap_to_wximage = cacheing(wxbitmap_to_wximage)
  77.  
  78. def wxbitmap_to_pil(wxbitmap):
  79.     return wximage_to_pil(wxbitmap_to_wximage(wxbitmap))
  80.  
  81. wxbitmap_to_pil = refmemoize(wxbitmap_to_pil)
  82.  
  83. def wxicon_to_pil(wxicon):
  84.     return wxbitmap_to_pil(BitmapFromIcon(wxicon))
  85.  
  86. wxicon_to_pil = cacheing(wxicon_to_pil)
  87.  
  88. def wxicon_to_bitmap(wxicon):
  89.     return BitmapFromIcon(wxicon)
  90.  
  91. wxicon_to_bitmap = cacheing(wxicon_to_bitmap)
  92.  
  93. def wximage_to_pil(wximage):
  94.     size = (wximage.Width, wximage.Height)
  95.     img = Image.new('RGB', size)
  96.     img.fromstring(wximage.Data)
  97.     (r, g, b) = img.split()
  98.     if wximage.HasAlpha() or wximage.HasMask():
  99.         a = Image.new('L', wximage.GetSize())
  100.         if wximage.HasMask():
  101.             if not wximage.HasAlpha():
  102.                 wximage.InitAlpha()
  103.             
  104.         
  105.         if wximage.HasAlpha():
  106.             a.fromstring(wximage.AlphaData)
  107.         
  108.         img = Image.merge('RGBA', (r, g, b, a))
  109.     else:
  110.         img = Image.merge('RGB', (r, g, b))
  111.     return img
  112.  
  113. wximage_to_pil = refmemoize(wximage_to_pil)
  114.  
  115. def wximage_to_wxbitmap(wximage, depth = 32):
  116.     return BitmapFromImage(wximage)
  117.  
  118.  
  119. def pil_to_wxbitmap(pilimg):
  120.     return wximage_to_wxbitmap(pil_to_wximage(pilimg), 32)
  121.  
  122. pil_to_wxbitmap = objmemoize(pil_to_wxbitmap)
  123.  
  124. def pil_to_wximage(pilimg):
  125.     pilimage = None if pilimg.mode == 'RGBA' else pilimg.convert('RGBA')
  126.     (w, h) = pilimg.size
  127.     rgb = pilimage.tostring('raw', 'RGB')
  128.     alpha = pilimage.tostring('raw', 'A')
  129.     return ImageFromDataWithAlpha(w, h, rgb, alpha)
  130.  
  131. pil_to_wximage = objmemoize(pil_to_wximage)
  132.  
  133. def wxbitmap_inverted(wxbitmap):
  134.     return ImageOps.invert(pilimg_convert(wxbitmap.PIL, 'RGB')).WXB
  135.  
  136. wxbitmap_inverted = cacheing(wxbitmap_inverted)
  137.  
  138. def has_transparency(i):
  139.     return any(i.histogram()[768:1024])
  140.  
  141.  
  142. def pil_to_white_gif(i):
  143.     bg = Image.new('RGBA', i.size, (255, 255, 255, 255))
  144.     bg.paste(i, i)
  145.     return pil_to_gif(bg)
  146.  
  147.  
  148. def pil_to_gif(i):
  149.     import cStringIO
  150.     s = cStringIO.StringIO()
  151.     (r, g, b, a) = i.split()
  152.     rgb = Image.merge('RGB', (r, g, b))
  153.     rgb = rgb.convert('P', palette = Image.ADAPTIVE, colors = 255, dither = Image.NONE)
  154.     pal = rgb.getpalette()
  155.     if len(pal) < 768:
  156.         r1 = pal[::3]
  157.         g1 = pal[1::3]
  158.         b1 = pal[2::3]
  159.         rv = (set(xrange(256)) - set(r1)).pop()
  160.         gv = (set(xrange(256)) - set(g1)).pop()
  161.         bv = (set(xrange(256)) - set(b1)).pop()
  162.         pal[-3:] = [
  163.             rv,
  164.             gv,
  165.             bv]
  166.         rgb.putpalette(pal, rawmode = 'RGB')
  167.         a2 = a.point((lambda p: if p >= 128:
  168. 0255))
  169.         rgb.paste(255, (0, 0), a2)
  170.         rgb.save(s, 'GIF', transparency = 255, interlace = False)
  171.     else:
  172.         rgb.putpalette(pal, rawmode = 'RGB')
  173.         rgb.save(s, 'GIF', interlace = False)
  174.     return s.getvalue()
  175.  
  176.  
  177. def wxbitmap_resizedwh(wxbitmap, w, h):
  178.     return pil_to_wxbitmap(pilimg_resizedwh(wximage_to_pil(wxbitmap_to_wximage(wxbitmap)), w, h))
  179.  
  180. wxbitmap_resizedwh = refmemoize(wxbitmap_resizedwh)
  181.  
  182. def wxbitmap_resized(wxbitmap, size):
  183.     
  184.     try:
  185.         (w, h) = size
  186.     except TypeError:
  187.         return wxbitmap_in_square(wxbitmap, size)
  188.  
  189.     return wxbitmap_resizedwh(wxbitmap, w, h)
  190.  
  191. wxbitmap_resized = refmemoize(wxbitmap_resized)
  192.  
  193. def wxbitmap_resized_smaller(wxbitmap, size):
  194.     if max(wxbitmap.Width, wxbitmap.Height) > size:
  195.         return wxbitmap.Resized(size)
  196.     return wxbitmap
  197.  
  198.  
  199. def pil_resized_smaller(pil, size):
  200.     if max(pil.size) > size:
  201.         return pil.Resized(size)
  202.     return pil
  203.  
  204.  
  205. def pilimg_resized(pilimg, size):
  206.     
  207.     try:
  208.         (w, h) = size
  209.     except TypeError:
  210.         return pilimg_in_square(pilimg, size)
  211.  
  212.     return pilimg_resizedwh(pilimg, w, h)
  213.  
  214. pilimg_resized = objmemoize(pilimg_resized)
  215.  
  216. def pilimg_convert(pilimg, mode):
  217.     return pilimg.convert(mode)
  218.  
  219. pilimg_convert = objmemoize(pilimg_convert)
  220.  
  221. def pilimg_resizedwh(pilimg, w, h):
  222.     w = None if w == -1 else int(w)
  223.     h = None if h == -1 else int(h)
  224.     size = (w, h)
  225.     if pilimg.mode == 'P':
  226.         pilimg = pilimg_convert(pilimg, 'RGBA')
  227.     
  228.     return None(pilimg.resize, size if min(size) < min(pilimg.size) else Image.BICUBIC)
  229.  
  230. pilimg_resizedwh = objmemoize(pilimg_resizedwh)
  231.  
  232. def pilimg_in_square(img, squaresize):
  233.     (w, h) = img.size
  234.     if img.mode == 'P':
  235.         img = pilimg_convert(img, 'RGBA')
  236.     
  237.     new = Image.new('RGBA', (squaresize, squaresize), (0, 0, 0, 0))
  238.     if w > h:
  239.         new_height = int((h / float(w)) * squaresize)
  240.         img = None(img.resize, (squaresize, new_height) if squaresize > w else ANTIALIAS)
  241.         new.paste(img, (0, (squaresize - new_height) / 2))
  242.     else:
  243.         new_width = int((w / float(h)) * squaresize)
  244.         img = None(img.resize, (new_width, squaresize) if squaresize > h else ANTIALIAS)
  245.         new.paste(img, ((squaresize - new_width) / 2, 0))
  246.     return new
  247.  
  248. pilimg_in_square = objmemoize(pilimg_in_square)
  249.  
  250. def pil_resize_canvas(img, w, h, alignment = wx.ALIGN_CENTER):
  251.     if alignment != wx.ALIGN_CENTER:
  252.         raise NotImplementedError
  253.     alignment != wx.ALIGN_CENTER
  254.     (ow, oh) = img.size
  255.     new = Image.new('RGBA', (w, h), (0, 0, 0, 0))
  256.     new.paste(img, (w / 2 - ow / 2, w / 2 - oh / 2))
  257.     return new
  258.  
  259. pil_resize_canvas = objmemoize(pil_resize_canvas)
  260.  
  261. def pil_setalpha(img, alpha):
  262.     channels = img.split()
  263.     if len(channels) == 4:
  264.         (r, g, b, a) = channels
  265.     elif len(channels) == 3:
  266.         a = Image.new('L', img.size, 'white')
  267.     else:
  268.         raise AssertionError('Cannot set alpha, image does not have 3 or 4 bands.')
  269.     (len(channels) == 4).putalpha(ImageEnhance.Brightness(a).enhance(alpha))
  270.  
  271.  
  272. def wxbitmap_in_square(bmp, squaresize, scaleup = True):
  273.     w = bmp.Width
  274.     h = bmp.Height
  275.     if w > squaresize and h > squaresize or scaleup:
  276.         img = ImageFromBitmap(bmp)
  277.         if w > h:
  278.             new_height = int((h / float(w)) * squaresize)
  279.             img = img.Scale(squaresize, new_height, IMAGE_QUALITY_HIGH)
  280.             offset = Point(0, (squaresize - new_height) / 2)
  281.         else:
  282.             new_width = int((w / float(h)) * squaresize)
  283.             img = img.Scale(new_width, squaresize, IMAGE_QUALITY_HIGH)
  284.             offset = Point((squaresize - new_width) / 2, 0)
  285.         return BitmapFromImage(img)
  286.     return bmp
  287.  
  288. wxbitmap_in_square = refmemoize(wxbitmap_in_square)
  289.  
  290. def wxbitmap_greyed(bitmap):
  291.     return wximage_to_wxbitmap(wxbitmap_to_wximage(bitmap).ConvertToGreyscale())
  292.  
  293. wxbitmap_greyed = refmemoize(wxbitmap_greyed)
  294.  
  295. def pilimg_greyed(pil):
  296.     pil = pil.copy()
  297.     alpha = 'A' in pil.getbands()
  298.     if alpha:
  299.         (r, g, b, a) = pil.split()
  300.     
  301.     pil = ImageOps.grayscale(pil)
  302.     if alpha:
  303.         pil.putalpha(a)
  304.     
  305.     return pil
  306.  
  307. pilimg_greyed = objmemoize(pilimg_greyed)
  308.  
  309. def drop_shadow(image, offset = (5, 5), background = (0, 0, 0, 0), shadow = 4473924, border = 8, iterations = 3):
  310.     image = image.PIL
  311.     totalWidth = image.size[0] + abs(offset[0]) + 2 * border
  312.     totalHeight = image.size[1] + abs(offset[1]) + 2 * border
  313.     back = Image.new(image.mode, (totalWidth, totalHeight), background)
  314.     shadowLeft = border + max(offset[0], 0)
  315.     shadowTop = border + max(offset[1], 0)
  316.     back.paste(shadow, [
  317.         shadowLeft,
  318.         shadowTop,
  319.         shadowLeft + image.size[0],
  320.         shadowTop + image.size[1]])
  321.     n = 0
  322.     while n < iterations:
  323.         back = back.filter(ImageFilter.BLUR)
  324.         n += 1
  325.     imageLeft = border - min(offset[0], 0)
  326.     imageTop = border - min(offset[1], 0)
  327.     back.paste(image, (imageLeft, imageTop))
  328.     return back
  329.  
  330.  
  331. def pil_combine(imgs, direction = wx.HORIZONTAL, align = wx.ALIGN_CENTER):
  332.     imgs = [ img.PIL for img in imgs ]
  333.     length_idx = [
  334.         wx.HORIZONTAL,
  335.         wx.VERTICAL].index(direction)
  336.     breadth_idx = [] if length_idx else 1
  337.     for img in imgs:
  338.         size = img.size
  339.         length += size[length_idx]
  340.         breadth = max(breadth, size[breadth_idx])
  341.     
  342.     newsize = length = breadth = 0 if direction == wx.HORIZONTAL else (breadth, length)
  343.     newimg = Image.new('RGBA', newsize, (0, 0, 0, 0))
  344.     pos = (0, 0)
  345.     for img in imgs:
  346.         newimg.paste(img, pos)
  347.         if direction == wx.HORIZONTAL:
  348.             pos = (pos[0] + img.size[0], pos[1])
  349.             continue
  350.         []
  351.         pos = (pos[0], pos[1] + img.size[1])
  352.     
  353.     return newimg
  354.  
  355.  
  356. def rounded_corners(corner_size = 1, rounded_imgs = { }):
  357.     if not isinstance(corner_size, int):
  358.         import util
  359.         corner_size = (util.try_this,)((lambda : int(bool(corner_size))), 1)
  360.     else:
  361.         corner_size = max(0, min(corner_size, 3))
  362.     
  363.     try:
  364.         return rounded_imgs[corner_size]
  365.     except KeyError:
  366.         pass
  367.  
  368.     imgs = []
  369.     skin = skin
  370.     import gui
  371.     rounded_img = Image.open(skin.resourcedir() / ('corner' + str(corner_size) + '.gif')).convert('L')
  372.     for name, rotation in CORNERS:
  373.         mask = None if rotation is not None else rounded_img
  374.         imgs.append(mask)
  375.     
  376.     return rounded_imgs.setdefault(corner_size, imgs)
  377.  
  378.  
  379. def rounded_mask(size, cornersize = 1):
  380.     img = Image.new('L', size, 255)
  381.     (w, h) = size
  382.     p = img.paste
  383.     r = rounded_corners(cornersize)
  384.     i = r[0]
  385.     p(i, (0, 0, i.size[0], i.size[1]))
  386.     i = r[1]
  387.     p(i, (w - i.size[0], 0, w, i.size[1]))
  388.     i = r[2]
  389.     p(i, (0, h - i.size[1], i.size[0], h))
  390.     i = r[3]
  391.     p(i, (w - i.size[0], h - i.size[1], w, h))
  392.     return img
  393.  
  394.  
  395. def pilimg_rounded(image, cornersize = 1):
  396.     newimage = image.copy()
  397.     newimage.putalpha(ImageMath.eval('convert(min(a,b), "L")', a = newimage.split()[-1], b = rounded_mask(newimage.size, cornersize)))
  398.     return newimage
  399.  
  400. pilimg_rounded = objmemoize(pilimg_rounded)
  401.  
  402. def wxbitmap_rounded(wxbitmap, cornersize = 1):
  403.     if cornersize == 0:
  404.         return wxbitmap
  405.     return pil_to_wxbitmap(pilimg_rounded(wximage_to_pil(wxbitmap_to_wximage(wxbitmap)), cornersize))
  406.  
  407. wxbitmap_rounded = refmemoize(wxbitmap_rounded)
  408.  
  409. def wxbitmap_decodedsize(b):
  410.     return None * b.Width * b.Height if not b.HasAlpha() else 4
  411.  
  412.  
  413. def wximage_decodedsize(i):
  414.     return i.Width * i.Height * 4
  415.  
  416.  
  417. def pil_decodedsize(p):
  418.     (width, height) = p.size
  419.     bpp = {
  420.         'RGBA': 4,
  421.         'RGB': 3,
  422.         'L': 1 }.get(p.mode, 0)
  423.     return width * height * bpp
  424.  
  425. Image.Image.Resized = pilimg_resized
  426. Image.Image.ResizedSmaller = pil_resized_smaller
  427. Image.Image.Rounded = pilimg_rounded
  428. Image.Image.WXB = property((lambda pil: pil_to_wxbitmap(pil)))
  429. Image.Image.WX = property((lambda pil: pil_to_wximage(pil)))
  430. Image.Image.Greyed = property(pilimg_greyed)
  431. Image.Image.ResizeCanvas = pil_resize_canvas
  432. Image.Image.PIL = property((lambda pil: pil))
  433. Image.Image.DecodedSize = property((lambda self: pil_decodedsize(self)))
  434. wx.Bitmap.Resized = wxbitmap_resized
  435. wx.Bitmap.ResizedSmaller = wxbitmap_resized_smaller
  436. wx.Bitmap.Greyed = property(wxbitmap_greyed)
  437. wx.Bitmap.Rounded = wxbitmap_rounded
  438. wx.Bitmap.WXB = property((lambda self: self))
  439. wx.Bitmap.WX = property((lambda wxb: wxbitmap_to_wximage(wxb)))
  440. wx.Bitmap.PIL = property((lambda self: wxbitmap_to_pil(self)))
  441. wx.Bitmap.Inverted = property(wxbitmap_inverted)
  442. wx.Bitmap.DecodedSize = property((lambda self: wxbitmap_decodedsize(self)))
  443. wx.Image.WX = property((lambda self: self))
  444. wx.Image.WXB = property((lambda self: wximage_to_wxbitmap(self, 32)))
  445. wx.Image.PIL = property((lambda self: wximage_to_pil(self)))
  446. wx.Image.DecodedSize = property((lambda self: wximage_decodedsize(self)))
  447. wx.Icon.PIL = property((lambda self: wxicon_to_pil(self)))
  448. wx.Icon.WXB = property((lambda self: wxicon_to_bitmap(self)))
  449.  
  450. def pil_to_wxb_nocache(pil):
  451.     return wx.BitmapFromImage(pil_to_wximage.nocache(pil))
  452.  
  453.  
  454. def wxb_to_pil_nocache(wxb):
  455.     return wximage_to_pil.nocache(wxb.ConvertToImage())
  456.  
  457. if __name__ == '__main__':
  458.     from tests.testapp import testapp
  459.     from gui.skin import get
  460.     a = testapp('../../..')
  461.     img = Image.new('RGBA', (40, 50), 'red')
  462.     img.Resized(100).Show()
  463.     a.MainLoop()
  464.  
  465.