2014-09-04 60 views
0

我试图从SWF中提取图像。下面的代码工作,但是当提取PNG图像时,背景变得不透明。任何帮助都会很棒。这是我有:使用PHP从SWF中提取图像时保持PNG透明度

class SWFextractImages { 
private $swf; 
private $jpegTables; 
private $shipID; 

public function doExtractImages($shipID, $b) { 
    $this->shipID = $shipID; 
    $this->swf = new SWF($b); 
    $this->jpegTables = ''; 
    foreach ($this->swf->tags as $tag) { 
     if($tag['type']==6){ 
      if($this->defineBits($tag)){ 
       continue; 
      } 
     } 
    } 
} 

private function defineBits($tag) { 
    $ret = $this->swf->parseTag($tag); 
    $imageData = $ret['imageData']; 
    if (strlen($this->jpegTables) > 0) { 
     $imageData = substr($this->jpegTables, 0, -2) . substr($imageData, 2); 
    } 
    if($ret['characterId']==5){ 
     $filename = sprintf('images/'.$this->shipID.'.jpg', $ret['characterId']); 
     file_put_contents($filename, $imageData); 
     return true; 
    } 
    } 

} 

不知道这是否会有所帮助,但这也从SWF文件中提取其他数据。 Here's the source code

回答

0

功能defineBits仅供JPG图像

对于PNG试试这个:

private function defineBitsLossless($tag) { 
$ret = $this->swf->parseTag($tag); 

$bitmapFormat = $ret['bitmapFormat']; 
$bitmapWidth = $ret['bitmapWidth']; 
$bitmapHeight = $ret['bitmapHeight']; 
$pixelData = $ret['pixelData']; 

$img = imageCreateTrueColor($bitmapWidth, $bitmapHeight); 

if ($bitmapFormat == 3) { 
    $colorTable = $ret['colorTable']; 

    // Construct the colormap 
    $colors = array(); 
    $i = 0; 
    $len = strlen($colorTable); 
    while ($i < $len) { 
    $red = ord($colorTable[$i++]); 
    $green = ord($colorTable[$i++]); 
    $blue = ord($colorTable[$i++]); 
    $colors[] = imageColorAllocate($img, $red, $green, $blue); 
    } 

    $bytesPerRow = $this->alignTo4bytes($bitmapWidth * 1); // 1 byte per sample 

    // Construct the image 
    for ($row = 0; $row < $bitmapHeight; $row++) { 
    $off = $bytesPerRow * $row; 
    for ($col = 0; $col < $bitmapWidth; $col++) { 
     $idx = ord($pixelData[$off++]); 
     imageSetPixel($img, $col, $row, $colors[$idx]); 
    } 
    } 
} else if ($bitmapFormat == 4) { 
    $bytesPerRow = $this->alignTo4bytes($bitmapWidth * 2); // 2 bytes per sample 

    // Construct the image 
    for ($row = 0; $row < $bitmapHeight; $row++) { 
    $off = $bytesPerRow * $row; 
    for ($col = 0; $col < $bitmapWidth; $col++) { 
     $lo = ord($pixelData[$off++]); 
     $hi = ord($pixelData[$off++]); 
     $rgb = $lo + $hi * 256; 
     $red = ($rgb >> 10) & 0x1f; // 5 bits 
     $green = ($rgb >> 5) & 0x1f; // 5 bits 
     $blue = ($rgb) & 0x1f; // 5 bits 
     $color = imageColorAllocate($img, $red, $green, $blue); 
     imageSetPixel($img, $col, $row, $color); 
    } 
    } 
} else if ($bitmapFormat == 5) { 
    $bytesPerRow = $this->alignTo4bytes($bitmapWidth * 4); // 4 bytes per sample 

    // Construct the image 
    for ($row = 0; $row < $bitmapHeight; $row++) { 
    $off = $bytesPerRow * $row; 
    for ($col = 0; $col < $bitmapWidth; $col++) { 
     $off++; // Reserved 
     $red = ord($pixelData[$off++]); 
     $green = ord($pixelData[$off++]); 
     $blue = ord($pixelData[$off++]); 
     $color = imageColorAllocate($img, $red, $green, $blue); 
     imageSetPixel($img, $col, $row, $color); 
    } 
    } 
} 
imagePNG($img, sprintf('images/img_%d.png', $ret['characterId'])); 
imageDestroy($img); 
} 

你可以阅读更多,了解更多,使用更从here

+0

一些问题上来;看起来我们试图获得的图像类型是35,这是带有guessextension函数的JPEG3。我们得到了使用它的图像,但图像仍然不透明。你有什么想法? – user3245228 2014-09-04 09:02:52

+0

首先,.jpg不能是透明的。你声称不透明的图像的扩展是什么? – 2014-09-04 09:06:03

+0

图片是PNG。它必须是,因为它们是SWF使用的渲染。但是当我们测试标签类型时,它返回35,这是DefineBitsJPEG3。 – user3245228 2014-09-04 09:07:37