From fab367cf41f0f03f81c6ca70ce4acd73b1d81dfc Mon Sep 17 00:00:00 2001 From: ThomasV Date: Fri, 6 Apr 2012 14:54:02 +0200 Subject: [PATCH] bitmaps --- client/bmp.py | 206 +++++++++++++++++++++++++++++++++++ client/electrum_text_320.png | Bin 0 -> 4882 bytes 2 files changed, 206 insertions(+) create mode 100644 client/bmp.py create mode 100644 client/electrum_text_320.png diff --git a/client/bmp.py b/client/bmp.py new file mode 100644 index 00000000..bfdd165b --- /dev/null +++ b/client/bmp.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +""" +bmp.py - module for constructing simple BMP graphics files + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +__version__ = "0.3" +__about = "bmp module, version %s, written by Paul McGuire, October, 2003, updated by Margus Laak, September, 2009" % __version__ + +from math import ceil, hypot + + +def shortToString(i): + hi = (i & 0xff00) >> 8 + lo = i & 0x00ff + return chr(lo) + chr(hi) + +def longToString(i): + hi = (long(i) & 0x7fff0000) >> 16 + lo = long(i) & 0x0000ffff + return shortToString(lo) + shortToString(hi) + +def long24ToString(i): + return chr(i & 0xff) + chr(i >> 8 & 0xff) + chr(i >> 16 & 0xff) + +def stringToLong(input_string, offset): + return ord(input_string[offset+3]) << 24 | ord(input_string[offset+2]) << 16 | ord(input_string[offset+1]) << 8 | ord(input_string[offset]) + +def stringToLong24(input_string, offset): + return ord(input_string[offset+2]) << 16 | ord(input_string[offset+1]) << 8 | ord(input_string[offset]) + +class Color(object): + """class for specifying colors while drawing BitMap elements""" + __slots__ = [ 'red', 'grn', 'blu' ] + __shade = 32 + + def __init__( self, r=0, g=0, b=0 ): + self.red = r + self.grn = g + self.blu = b + + def __setattr__(self, name, value): + if hasattr(self, name): + raise AttributeError, "Color is immutable" + else: + object.__setattr__(self, name, value) + + def __str__( self ): + return "R:%d G:%d B:%d" % (self.red, self.grn, self.blu ) + + def __hash__( self ): + return ( ( long(self.blu) ) + + ( long(self.grn) << 8 ) + + ( long(self.red) << 16 ) ) + + def __eq__( self, other ): + return (self is other) or (self.toLong == other.toLong) + + def lighten( self ): + return Color( + min( self.red + Color.__shade, 255), + min( self.grn + Color.__shade, 255), + min( self.blu + Color.__shade, 255) + ) + + def darken( self ): + return Color( + max( self.red - Color.__shade, 0), + max( self.grn - Color.__shade, 0), + max( self.blu - Color.__shade, 0) + ) + + def toLong( self ): + return self.__hash__() + + def fromLong( l ): + b = l & 0xff + l = l >> 8 + g = l & 0xff + l = l >> 8 + r = l & 0xff + return Color( r, g, b ) + fromLong = staticmethod(fromLong) + +# define class constants for common colors +Color.BLACK = Color( 0, 0, 0 ) +Color.RED = Color( 255, 0, 0 ) +Color.GREEN = Color( 0, 255, 0 ) +Color.BLUE = Color( 0, 0, 255 ) +Color.CYAN = Color( 0, 255, 255 ) +Color.MAGENTA = Color( 255, 0, 255 ) +Color.YELLOW = Color( 255, 255, 0 ) +Color.WHITE = Color( 255, 255, 255 ) +Color.DKRED = Color( 128, 0, 0 ) +Color.DKGREEN = Color( 0, 128, 0 ) +Color.DKBLUE = Color( 0, 0, 128 ) +Color.TEAL = Color( 0, 128, 128 ) +Color.PURPLE = Color( 128, 0, 128 ) +Color.BROWN = Color( 128, 128, 0 ) +Color.GRAY = Color( 128, 128, 128 ) + + +class BitMap(object): + """class for drawing and saving simple Windows bitmap files""" + + LINE_SOLID = 0 + LINE_DASHED = 1 + LINE_DOTTED = 2 + LINE_DOT_DASH=3 + _DASH_LEN = 12.0 + _DOT_LEN = 6.0 + _DOT_DASH_LEN = _DOT_LEN + _DASH_LEN + + def __init__( self, width, height, + bkgd = Color.WHITE, frgd = Color.BLACK ): + self.wd = int( ceil(width) ) + self.ht = int( ceil(height) ) + self.bgcolor = 0 + self.fgcolor = 1 + self.palette = [] + self.palette.append( bkgd.toLong() ) + self.palette.append( frgd.toLong() ) + self.currentPen = self.fgcolor + + tmparray = [ self.bgcolor ] * self.wd + self.bitarray = [ tmparray[:] for i in range( self.ht ) ] + self.currentPen = 1 + + + def plotPoint( self, x, y ): + if ( 0 <= x < self.wd and 0 <= y < self.ht ): + x = int(x) + y = int(y) + self.bitarray[y][x] = self.currentPen + + + def _saveBitMapNoCompression( self ): + line_padding = (4 - (self.wd % 4)) % 4 + + # write bitmap header + _bitmap = "BM" + _bitmap += longToString( 54 + self.ht*(self.wd*3 + line_padding) ) # DWORD size in bytes of the file + _bitmap += longToString( 0 ) # DWORD 0 + _bitmap += longToString( 54 ) + _bitmap += longToString( 40 ) # DWORD header size = 40 + _bitmap += longToString( self.wd ) # DWORD image width + _bitmap += longToString( self.ht ) # DWORD image height + _bitmap += shortToString( 1 ) # WORD planes = 1 + _bitmap += shortToString( 24 ) # WORD bits per pixel = 8 + _bitmap += longToString( 0 ) # DWORD compression = 0 + _bitmap += longToString( self.ht * (self.wd * 3 + line_padding) ) # DWORD sizeimage = size in bytes of the bitmap = width * height + _bitmap += longToString( 0 ) # DWORD horiz pixels per meter (?) + _bitmap += longToString( 0 ) # DWORD ver pixels per meter (?) + _bitmap += longToString( 0 ) # DWORD number of colors used = 256 + _bitmap += longToString( 0 ) # DWORD number of "import colors = len( self.palette ) + + # write pixels + self.bitarray.reverse() + for row in self.bitarray: + for pixel in row: + c = self.palette[pixel] + _bitmap += long24ToString(c) + for i in range(line_padding): + _bitmap += chr( 0 ) + + return _bitmap + + + + def saveFile( self, filename): + _b = self._saveBitMapNoCompression( ) + + f = file(filename, 'wb') + f.write(_b) + f.close() + + + + + + +if __name__ == "__main__": + + bmp = BitMap( 10, 10 ) + bmp.plotPoint( 5, 5 ) + bmp.plotPoint( 0, 0 ) + bmp.saveFile( "test.bmp" ) + diff --git a/client/electrum_text_320.png b/client/electrum_text_320.png new file mode 100644 index 0000000000000000000000000000000000000000..dc6f086440b839c2323ba8692ce8cb13e1f7e310 GIT binary patch literal 4882 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 A@&Et; literal 0 HcmV?d00001