2013-02-11 113 views
-7

我使用python 2.7从hexa字符串获取图像

我在DB中有一个字符串表示Hexa中的图像。例如

sdata = "789C9D953D56C52010856363696D49E90AAC73ECDD4396C25228B210CE711B2CC2CAC622CECC9D0C0321313A27E411123EEEFCC07B7BFF7A9CC45EA9BD507BD6F620F769CAF4FEE3096DB76DDACEAEE9865D4CF79C6DAB34F46D441F7F23F88F6F728E6AD794724EDD5CBB9B790EF53FBF1595D9524C517E93CDEA3A433D984E83440327B318B633BF867A4C12734A5654CE26F24F29AB28704A067685363C665B0582D30ADF0F39A2717F3979C9412A6108A1D731C6992C04BD96252ECB9A2AC4A60F2B07904AA8166C84B51545D172C3C8D02B4CA3D51D841F7584B5CD2E17E2698A5DDE991302AD6240189666558242122D68F1C0F19F99475104D0F7C6216D5A6665AFAED62F8A27730A57E3BC4858669D25716B387BA04E39B41059BCC7E99CEAF4B05F971C75AAB0181AE938111CA9DB9A71C9B5443EA000D4231183A4F8ECEF79E7E5B40E2DEF647BDEA9AB6250EA59F70B6AC90E9FAABFB7D040E43C010107D4F1086A4ADA6D8DA66C8AEDD9C10E3514196A0F060220B59825C843883F5D71A67586809FEDF17FFCD75C4CFC012B43550B" 

现在,我想使用此字符串创建图像。我知道该图像是24x24 BMP(或PNG?)图像。

我知道php代码来得到它,但不是python。

PHP:

function imagecreatefrombmpstring($im) { 
    $header = unpack("vtype/Vsize/v2reserved/Voffset", substr($im, 0, 14)); 
    $info = unpack("Vsize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vncolor/Vimportant", substr($im, 14, 40)); 
    extract($info); 
    extract($header); 
    if($type != 0x4D42) 
      return false; 
    $palette_size = $offset - 54; 
    $ncolor = $palette_size/4; 
    $imres=imagecreatetruecolor($width, $height); 
    imagealphablending($imres, false); 
    imagesavealpha($imres, true); 
    $pal=array(); 
    if($palette_size) { 
      $palette = substr($im, 54, $palette_size); 
      $gd_palette = ""; 
      $j = 0; $n = 0; 
      while($j < $palette_size) { 
        $b = ord($palette{$j++}); 
        $g = ord($palette{$j++}); 
        $r = ord($palette{$j++}); 
        $a = ord($palette{$j++}); 
        if (($r == 255) && ($g == 0) && ($b == 255)) 
          $a = 127; // alpha = 255 on 0xFF00FF 
        $pal[$n++] = imagecolorallocatealpha($imres, $r, $g, $b, $a); 
      } 
    } 
    $scan_line_size = (($bits * $width) + 7) >> 3; 
    $scan_line_align = ($scan_line_size & 0x03) ? 4 - ($scan_line_size & 0x03): 0; 
    for($i = 0, $l = $height - 1; $i < $height; $i++, $l--) { 
      $scan_line = substr($im, $offset + (($scan_line_size + $scan_line_align) * $l), $scan_line_size); 
      if($bits == 24) { 
        $j = 0; $n = 0; 
        while($j < $scan_line_size) { 
          $b = ord($scan_line{$j++}); 
          $g = ord($scan_line{$j++}); 
          $r = ord($scan_line{$j++}); 
          $a = 0; 
          if (($r == 255) && ($g == 0) && ($b == 255)) 
            $a = 127; // alpha = 255 on 0xFF00FF 
          $col=imagecolorallocatealpha($imres, $r, $g, $b, $a); 
          imagesetpixel($imres, $n++, $i, $col); 
        } 
      } 
      else if($bits == 8) { 
        $j = 0; 
        while($j < $scan_line_size) { 
          $col = $pal[ord($scan_line{$j++})]; 
          imagesetpixel($imres, $j-1, $i, $col); 
        } 
      } 
      else if($bits == 4) { 
        $j = 0; $n = 0; 
        while($j < $scan_line_size) { 
          $byte = ord($scan_line{$j++}); 
          $p1 = $byte >> 4; 
          $p2 = $byte & 0x0F; 
          imagesetpixel($imres, $n++, $i, $pal[$p1]); 
          imagesetpixel($imres, $n++, $i, $pal[$p2]); 
        } 
      } 
      else if($bits == 1) { 
        $j = 0; $n = 0; 
        while($j < $scan_line_size) { 
          $byte = ord($scan_line{$j++}); 
          $p1 = (int) (($byte & 0x80) != 0); 
          $p2 = (int) (($byte & 0x40) != 0); 
          $p3 = (int) (($byte & 0x20) != 0); 
          $p4 = (int) (($byte & 0x10) != 0); 
          $p5 = (int) (($byte & 0x08) != 0); 
          $p6 = (int) (($byte & 0x04) != 0); 
          $p7 = (int) (($byte & 0x02) != 0); 
          $p8 = (int) (($byte & 0x01) != 0); 
          imagesetpixel($imres, $n++, $i, $pal[$p1]); 
          imagesetpixel($imres, $n++, $i, $pal[$p2]); 
          imagesetpixel($imres, $n++, $i, $pal[$p3]); 
          imagesetpixel($imres, $n++, $i, $pal[$p4]); 
          imagesetpixel($imres, $n++, $i, $pal[$p5]); 
          imagesetpixel($imres, $n++, $i, $pal[$p6]); 
          imagesetpixel($imres, $n++, $i, $pal[$p7]); 
          imagesetpixel($imres, $n++, $i, $pal[$p8]); 
        } 
      } 
    } 
    return $imres; 
} 
$data = @gzuncompress(pack('H*', $sdata)); 
$image = imagecreatefrombmpstring($data); 

我找到http://code.google.com/p/fluxcp/source/browse/branches/fluxcp-1.0/modules/guild/emblem.php?r=696

你能帮助我这个代码。

EDIT ::

溶液

from binascii import unhexlify 
    import zlib 
    import Image 
    from cStringIO import StringIO 
    data = StringIO(zlib.decompress(unhexlify(sdata))) 
    i = Image.open(data) 
    i.show() 
+0

您的数据是否被压缩? – 2013-02-11 14:01:17

+0

我不知道,因为我使用的数据库,我没有做。我试图找到一种方式来显示图像。但是,如果我们查看php代码,我们会看到“gzuncompress”,所以我认为数据压缩zlib。 – Krozark 2013-02-11 14:03:34

+0

14个字节的信息和40个字节的标题指向BMP格式。 – 2013-02-11 14:17:28

回答

3

溶液(与OP合作)是:

import PIL 
from binascii import unhexlify 
import zlib 
from cStringIO import StringIO 

sdata = "789C9D953D56C52010856363696D49E90AAC73ECDD4396C25228B210CE711B2CC2CAC622CECC9D0C0321313A27E411123EEEFCC07B7BFF7A9CC45EA9BD507BD6F620F769CAF4FEE3096DB76DDACEAEE9865D4CF79C6DAB34F46D441F7F23F88F6F728E6AD794724EDD5CBB9B790EF53FBF1595D9524C517E93CDEA3A433D984E83440327B318B633BF867A4C12734A5654CE26F24F29AB28704A067685363C665B0582D30ADF0F39A2717F3979C9412A6108A1D731C6992C04BD96252ECB9A2AC4A60F2B07904AA8166C84B51545D172C3C8D02B4CA3D51D841F7584B5CD2E17E2698A5DDE991302AD6240189666558242122D68F1C0F19F99475104D0F7C6216D5A6665AFAED62F8A27730A57E3BC4858669D25716B387BA04E39B41059BCC7E99CEAF4B05F971C75AAB0181AE938111CA9DB9A71C9B5443EA000D4231183A4F8ECEF79E7E5B40E2DEF647BDEA9AB6250EA59F70B6AC90E9FAABFB7D040E43C010107D4F1086A4ADA6D8DA66C8AEDD9C10E3514196A0F060220B59825C843883F5D71A67586809FEDF17FFCD75C4CFC012B43550B" 

fh = StringIO(zlib.decompress(unhexlify(sdata))) 

image = PIL.Image.open(fh) 

PIL是Python图像库,以及使用StringIO的,我装拥有一个类似文件的对象。

+0

fh = StringIO(zlib.decompress(unhexlify(sdata))) i = Image.open(fh) i.show() 没关系。谢谢 – Krozark 2013-02-11 14:31:03

+0

我相应地更新了我的答案。很高兴帮助。 – 2013-02-11 14:38:57