我正在寻找使用此内容从字符串中写入1位位图的可能性:
$str = "001011000111110000";
零是白色,一个是黑色。 BMP文件为18 x 1 px。
我不想要24位BMP,而是真正的1位BMP。
有没有人知道PHP中的标头和转换方法?
答案 0 :(得分:3)
这是一个奇怪的请求:)
所以,你想在这里使用的是php-gd,一开始。通常这是在任何具有体面回购的操作系统上安装php时都包含的,但只是因为它不适合你,你可以在这里获得安装说明;
http://www.php.net/manual/en/image.setup.php
首先,我们需要确定图像在宽度上需要多大的尺寸;身高显然总是一个。
因此;
$str = $_GET['str'];
$img_width = strlen($str);
strlen将告诉我们$ str字符串中有多少个字符,因为我们给每个字符一个像素,所以字符数量将为我们提供所需的宽度。
为了便于访问,将字符串拆分为一个数组 - 每个单独的像素都有一个元素。
$color_array = str_split($str);
现在,让我们设置一个“指针”,我们正在绘制的像素。它是php所以你不需要为此做一些事情,但是整洁很好。
$current_px = (int) 0;
现在你可以初始化GD并开始制作图像;
$im = imagecreatetruecolor($img_width, 1);
// Initialise colours;
$black = imagecolorallocate($im, 0, 0, 0);
$white = imagecolorallocate($im, 255, 255, 255);
// Now, start running through the array
foreach ($color_array as $y)
{
if ($y == 1)
{
imagesetpixel ( $im, $current_px , 1 , $black );
}
$current_px++; // Don't need to "draw" a white pixel for 0. Just draw nothing and add to the counter.
}
这将绘制您的图像,然后您需要做的就是显示它;
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
请注意,根本不需要$ white声明 - 我只是将其留下来让您了解如何使用gd声明不同的颜色。
在使用之前你可能需要稍微调试一下 - 自从我使用GD以来已经很长时间了。无论如何,希望这有帮助!
答案 1 :(得分:1)
要创建没有 gd 或 imagemagick 的单色位图图像,您可以使用 pack 将机器字节顺序转换为小端字节顺序和一些处理字符串的函数,有关参考和更多详细信息,您可以查看维基百科第 bitmap file format 页或 3v4l 上的此脚本。
对于这个例子,我将使用一个更复杂的输入,这只是为了更好地解释在创建位图时每行应该如何对齐;
<?php
$pixelDataArray = array(
"11101010111",
"10101010101",
"11101110111",
"10001010100",
"10001010100",
);
首先将输入转换成像素阵列或位图数据,像素阵列上的每一行都应该是dword/32bit/4bytes对齐的。
$pixelWidth = strlen($pixelDataArray[0]);
$pixelHeight = count($pixelDataArray);
$dwordAlignment = 32 - ($pixelWidth % 32);
if ($dwordAlignment == 32) {
$dwordAlignment = 0;
}
$dwordAlignedLength = $pixelWidth + $dwordAlignment;
现在我们可以正确对齐字符串,然后将其转换为 1 字节整数数组,然后转换为二进制字符串。
$pixelArray = '';
foreach (array_reverse($pixelDataArray) as $row) {
$dwordAlignedPixelRow = str_pad($row, $dwordAlignedLength, '0', STR_PAD_RIGHT);
$integerPixelRow = array_map('bindec', str_split($dwordAlignedPixelRow, 8));
$pixelArray .= implode('', array_map('chr', $integerPixelRow));
}
$pixelArraySize = \strlen($pixelArray);
然后让我们建立颜色表
$colorTable = pack(
'CCCxCCCx',
//blue, green, red
255, 255, 255, // 0 color
0, 0, 0 // 1 color
);
$colorTableSize = \strlen($colorTable);
现在位图信息头,为了更好地支持BITMAPINFOHEADER(40字节头)将被使用。
$dibHeaderSize = 40;
$colorPlanes = 1;
$bitPerPixel = 1;
$compressionMethod = 0; //BI_RGB/NONE
$horizontal_pixel_per_meter = 2835;
$vertical_pixel_per_meter = 2835;
$colorInPalette = 2;
$importantColors = 0;
$dibHeader = \pack('VVVvvVVVVVV', $dibHeaderSize, $pixelWidth, $pixelHeight, $colorPlanes, $bitPerPixel, $compressionMethod, $pixelArraySize, $horizontal_pixel_per_meter, $vertical_pixel_per_meter, $colorInPalette, $importantColors);
最后一部分是文件头
$bmpFileHeaderSize = 14;
$pixelArrayOffset = $bmpFileHeaderSize + $dibHeaderSize + $colorTableSize;
$fileSize = $pixelArrayOffset + $pixelArraySize;
$bmpFileHeader = pack('CCVxxxxV', \ord('B'), \ord('M'), $fileSize, $pixelArrayOffset);
现在只需将所有内容连接成一个字符串即可使用。
$bmpFile = $bmpFileHeader . $dibHeader . $colorTable . $pixelArray;
$bmpBase64File = base64_encode($bmpFile);
?>
<img src="data:image/bitmap;base64, <?= $bmpBase64File ?>" style="image-rendering: crisp-edges;width: 100px;"/>
<img src="data:image/bitmap;base64, Qk1SAAAAAAAAAD4AAAAoAAAACwAAAAUAAAABAAEAAAAAABQAAAATCwAAEwsAAAIAAAAAAAAA////AAAAAACKgAAAioAAAO7gAACqoAAA6uAAAA==" style="image-rendering: crisp-edges;width: 100px;height: ;"/>
答案 2 :(得分:0)
这不是一个奇怪的请求。
我完全同意这个问题的目的,实际上我必须管理一些1bit的单色图像。
答案是:
imagecreate()
或imagecreatetruecolor()
imagecreatefrompng()
加载它来解决。另外:我刚从这里下载了官方库开源代码Official Bitbucket Repository
我在gd.h
找到了什么?:
上述功能的定义:
/* Functions to manipulate images. */
/* Creates a palette-based image (up to 256 colors). */
BGD_DECLARE(gdImagePtr) gdImageCreate (int sx, int sy);
/* An alternate name for the above (2.0). */
\#define gdImageCreatePalette gdImageCreate
/* Creates a truecolor image (millions of colors). */
BGD_DECLARE(gdImagePtr) gdImageCreateTrueColor (int sx, int sy);
所以“官方”解决方案是:使用imagecreate()
创建一个2色调色板图像(包装gdImageCreate()
GD功能)。
“替代”解决方案是创建一个外部图像,1位单色png,并使用imagecreatefrompng()
,如上所述。