【问题标题】:Create 1 bit bitmap (monochrome) in php在 php 中创建 1 位位图(单色)
【发布时间】:2012-06-23 07:24:16
【问题描述】:

我正在寻找从具有此内容的字符串中写入 1 位位图的可能性:

$str = "001011000111110000";

零是白色,一是黑色。 BMP 文件将为 18 x 1 像素。

我不想要一个 24 位 BMP,而是一个真正的 1 位 BMP。

有谁知道PHP中的标头和转换方法吗?

【问题讨论】:

  • +1 有趣的问题!

标签: php bitmap bit


【解决方案1】:

这是一个有点奇怪的要求:)

所以,您首先要在这里使用 php-gd。通常,在任何具有不错 repo 的操作系统上安装 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 以来已经有很长时间了。无论如何,希望这会有所帮助!

【讨论】:

  • 感谢您的回复,但我正在寻找一个 1bit 单色的 bmp 生成器,可能是纯 php。最后我找到了正确的方法和解决方案,现在我可以生成正确的 1bit bmp 单色图像了!使用此解决方案,我可以生成尺寸尽可能小的条码光栅图像,以供打印开膛手使用。
  • 啊,我明白了。好吧,我找到了一些可以帮助您使用 GD 创建 BMP 图像的类;你可以在这里找到这些:phpclasses.org/package/…我希望其余的信息至少对你有用:)
【解决方案2】:

这不是一个奇怪的要求。

我完全同意问题的目的,实际上我必须管理一些 1bit 单色图像。

答案是:

  • PHP 网站中没有很好地记录 GD。
  • 当你想从头开始创建图像时,你必须使用imagecreate()imagecreatetruecolor()
  • 看来刚才提到的两种方法(函数)都无法从头创建1bit图像。
  • 我通过创建一个外部图像来解决这个问题,1 位单色 png,并使用 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()(包装gdImageCreate() GD 函数)创建一个2 调色板图像。

“替代”解决方案是创建一个外部图像,1 位单色 png,并使用 imagecreatefrompng(),如上所述。

【讨论】:

  • 您能否给出“我通过创建外部图像来解决的代码示例,1bit 单色 png,使用 imagecreatefrompng() 加载它。”
【解决方案3】:

要创建没有 gd 或 imagemagick 的单色位图图像,您可以使用 pack 将机器字节顺序转换为小端字节顺序和一些用于处理字符串的函数,有关参考和更多详细信息,您可以查看维基百科页面 @ 987654322@ 或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;"/>

&lt;img src="data:image/bitmap;base64, Qk1SAAAAAAAAAD4AAAAoAAAACwAAAAUAAAABAAEAAAAAABQAAAATCwAAEwsAAAIAAAAAAAAA////AAAAAACKgAAAioAAAO7gAACqoAAA6uAAAA==" style="image-rendering: crisp-edges;width: 100px;height: ;"/&gt;

【讨论】:

    猜你喜欢
    • 2012-11-03
    • 2023-04-08
    • 2015-09-29
    • 2015-06-07
    • 2022-09-28
    • 2012-03-11
    • 2019-09-18
    • 2019-01-08
    • 1970-01-01
    相关资源
    最近更新 更多