从十六进制字符串中获取图

时间:2013-02-11 13:48:24

标签: php python image zlib

我使用python 2.7

我在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()

1 个答案:

答案 0 :(得分: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 Imaging Library,使用StringIO,我假装有一个类似文件的对象。