Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/229.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用php-GD实现单像素操作_Php_Image Processing_Php Gd - Fatal编程技术网

用php-GD实现单像素操作

用php-GD实现单像素操作,php,image-processing,php-gd,Php,Image Processing,Php Gd,首先我指的是前面的一个问题 我发现html5画布不适合,因为很难对源图像保密。这就是为什么我要用PHPGD库来实现我的目标。我从来没有在这个图书馆工作过,所以我遇到了一些困难。我想我需要以下功能 ImageCreateTureColor用于在浏览器中创建图像 imagecolorallocate用于从源图像返回rgb imagesetpixel用于绘制随机像素 $x = 200; //width of image $y = 200; //height of image $gd = image

首先我指的是前面的一个问题

我发现html5画布不适合,因为很难对源图像保密。这就是为什么我要用PHPGD库来实现我的目标。我从来没有在这个图书馆工作过,所以我遇到了一些困难。我想我需要以下功能

  • ImageCreateTureColor用于在浏览器中创建图像
  • imagecolorallocate用于从源图像返回rgb
  • imagesetpixel用于绘制随机像素

    $x = 200; //width of image
    $y = 200; //height of image
    
    $gd = imagecreatetruecolor ($x, $y);
     $color = imagecolorallocate($gd, $r, $g, $b) //not sure how to retrieve the rgb from the source image
    
    Then I need a function for drawing random pixels with imagesetpixel.
    imagesetpixel($gd, $posx,$posy, $color); // not sure how to retrieve the x and y position of each pixel.
    

我不是PHP的明星,这就是为什么我的搜索被这些GD函数卡住了。希望您能给我一个启动

用您的随机颜色值替换随机颜色

这将替换所有像素

for($i=0;$i < $x;$i++) {
    for($e = 0;$e < $y;$e++) {
        imagesetpixel($gd, $i,$e, $RANDOM_COLOR);
    }
}

你可以在一个循环中使用它,在食人魔的帮助下,我让它部分工作

我所做的是操纵顶层,操纵后,将其与函数imagecopy和源图像合并。输出为jpg图像

顶层的操作是用这段代码完成的

for ($y = 0; $y < imagesy($img); $y++) {
for ($x = 0; $x < imagesx($img); $x++) {
$img = imagecreatefrompng("thecover.png");
    imagealphablending($img, false); // Turn off blending
    $white_color_transparent = imagecolorallocatealpha($img, 255, 255, 255, 127);

            $rgb = imagecolorat($img, $x, $y);
            $pixel_color = imagecolorsforindex($img, $rgb);
            if ($pixel_color['red'] == 255 && $pixel_color['green'] == 255 && $pixel_color['blue'] == 255){
                for ($i = 0; $i < 200; $i++) {
                    imagesetpixel($img, rand(0,300), rand(0,300), $white_color_transparent);
                    }
            }
}
}
for($y=0;$y
顶层的颜色为白色,RGB(0,0,0)。脚本将检查该颜色,并在此时将200个随机像素设置为透明

它将很多像素设置为透明,但不是给定的200像素

有人能帮我解决问题。

随机函数的一个“特点”是它是伪随机的,也就是说,给定相同的种子,它总是输出相同的序列

因此,您可以为每个“图像”存储:

因此,假设您希望输出图像
$sourcefile
,其中包含可见像素百分比的种子
$seed
$position
。您甚至不需要使用alpha:

// Load image
$src = imageCreateFromPNG($sourcefile); // Assume image is PNG

// Create work image
$new = imageCreateTrueColor(ImageSX($src), ImageSY($src)); // new image of same size

mt_srand($seed); // Seed the Mersenne Twister generator

// Number of pixels to set: $position = 0: NONE, $position = 100: ALL
$pixels = round($position*imageSX($src)*imageSY($src)/100);

// Now we have a problem: if we do $pixels attempts, mt_rand might sometimes
// return the same pixel again. So we end up setting less than $pixels pixels.

// So we do this the expensive way, saving an array of yet-to-be-used pixels.
$max     = ImageSX($src)*ImageSY($src);
$pixelid = array();
for ($i = 0; $i < $max; $i++)
    $pixelid[] = $i;

$W  = ImageSX($src);

while($pixels--)
{
    // Extract one pixel
    $chosen = $pixelid[$idx = mt_rand(0, $pixels)];

    array_splice ($pixelid, $idx, 1); // Remove extracted pixel from array

    $x = $chosen % $W;
    $y = ($chosen - $x)/ $W;

    $rgb = imagecolorat($src, $x, $y);
    $pix = imagecolorsforindex($src, $rgb);
    $rgb = imageColorAllocate($new, $pix['red'], $pix['green'], $pix['blue']);
    imageSetPixel($new, $x, $y, $rgb);
}

ImageDestroy($src);

// $new has now exactly $pixels set to the same pixels of $src,
// the rest are undefined (you can fill $new with white beforehand...)
Header("Content-Type: image/png");
ImagePNG($new);
或者你可以。。。重试。但当图像几乎完成时,这可能会很昂贵

$cnt = count($pixelid);
while($pixels--)
{
    // Extract one pixel
    for ($idx = mt_rand(0, $cnt); $pixelid[$idx] != -1; $idx = mt_rand(0, $cnt))
        ;
    $chosen = $pixelid[$idx];
    $pixelid[$idx] = -1;
如果您不关心图像总是以不同的方式重建,则可以使用
数组\u shuffle()
而不是
mt\u rand()
,并在每次迭代时从
$pixelid
提取第i个像素

最后一个选项是使用
mt\u rand
重新实现
array\u shuffle()

因此,您可以使用
$seed
$pixelid
调用
array\u new\u shuffle()
,然后按顺序从无序数组中提取元素:

for ($idx = 0; $idx < $pixels; $idx++)
{
    $chosen = $pixelid[$idx];
    ...
优化 您会注意到上面代码中有一个注释部分。如果碰巧
$position
大于50%,比如70%,那么创建空图像并将70%的像素从良好图像复制到空图像是没有意义的。将30%的空像素从空图像复制到好图像上,使其“变黑”更有意义。这可以通过简单地交换
$new
$src
并调整
$position
来实现。我还没有完全测试过这段代码;这就是我留下评论的原因。但是欢迎你尝试一下

实施 使用PRNG的优点是不需要保存任何图像,只需要
种子
位置
——通常总共八个字节

如果人员A接收到位置1,并要求接收最多5个位置(即图像可见的5%),并且您保存种子和该值5,并将其用于人员B,则人员B将看到与人员A相同的5%

除原始图像外,所有图像均未保存或加载

如果您可以在$\u GET参数中传递种子和位置,则可以在浏览器中显示不同阶段的图像(例如,
image.php?seed=12345678&position=5
将显示设置了5%像素的图像。当然,您也可以指定像素数而不是百分比)


只要像素是随机选择的,这种方法就有效:如果一个人要选择他或她想要的确切像素,那么这种方法无效,你需要保存单个像素的位置,这可以通过几种方式实现:使用一个以二进制格式保存(x,y)对的平面文件,或者保存整个图像。后一种方法更容易理解,并且每一步都需要存储一个完整的图像,因此如果这是一个游戏,并且您想要“重放”它,那么您可能需要巨大的磁盘空间。第一种方法可能合理地要求每个像素有六个字节,即相当于具有相同高度且宽度为原始图像两倍的图像,或者每个像素只有四个字节。

感谢食人魔的回复。但是颜色不一定是随机的。输出的每个像素值(rgb和x,y)都需要与源图像相同。唯一的问题是,imagesetpixel并不是在一个步骤中绘制整个图像,而是在每个步骤的随机位置绘制随机数量的像素(所谓步骤,我指的是人们从表单中选择的像素数量)。在每一步之后,图片都需要保存到数据库中,以便下次看到相同数量的像素。像素数量将增加,因此浏览器中的图像将与源图像相似。您可以使用imagecopy将图像的一部分复制到另一个图像中,这样您将向用户显示此复制的图像,然后保存显示的x/y,在表单提交后,您将增加x和y。。。最后
$cnt = count($pixelid);

while($pixels--)
{
    // Extract one pixel
    $idx = mt_rand(0, $cnt);
    // If the extracted pixel is null, find next pixel that is unextracted
    // and if there are none, restart from the beginning of the array.
    while (-1 == ($chosen = $pixelid[$idx]))
        if ($cnt == ++$idx)
            $idx = 0;
    $chosen = $pixelid[$idx];
    $pixelid[$idx] = -1;
$cnt = count($pixelid);
while($pixels--)
{
    // Extract one pixel
    for ($idx = mt_rand(0, $cnt); $pixelid[$idx] != -1; $idx = mt_rand(0, $cnt))
        ;
    $chosen = $pixelid[$idx];
    $pixelid[$idx] = -1;
function array_new_shuffle(&$items, $seed)
{
    mt_srand($seed);
    for ($i = count($items) - 1; $i > 0; $i--)
    {
        $j = @mt_rand(0, $i);
        list($items[$i], $items[$j]) = array($items[$j], $items[$i]);
    }
}
for ($idx = 0; $idx < $pixels; $idx++)
{
    $chosen = $pixelid[$idx];
    ...
$seed = 0;
$position = 2;
$sourcefile = '/home/lserni/Lena19721024-filtered.png';

mt_srand($seed); // Seed the Mersenne Twister generator

// Load image
    $src = ImageCreateTrueColor(512,512);
// $src = imageCreateFromPNG($sourcefile); // Assume image is PNG
$W  = ImageSX($src);
$H  = ImageSY($src);

// Total number of pixels
$size   = $W*$H;

if (($W > 4095) || ($H > 4095))
   die("Image too big");

// Create work image
$new = imageCreateTrueColor($W, $H); // new image of same size

/*
if ($position > 50)
{
    $position = 100-$position;
    $tmp = $src;
    $src = $new;
    $new = $tmp;
}
*/

// Number of pixels to set: $position = 0: NONE, $position = 100: ALL
$pixels = round($position*$size/100.0);

// Create a temporary buffer image of the same size
$fix = imageCreateTrueColor($W, $H);
for ($i = 0; $i < $size; $i++)
{
    $b = $i & 0xFF;
    $g = ($i >> 8) & 0xFF;
    $r = ($i >> 16) & 0xFF;
    imageSetPixel($fix, $i % $W, floor($i / $W), imageColorAllocate($fix, $r, $g, $b));
}

while($pixels--)
{
    // Recover one of the available pixel indexes
    $idx = mt_rand(0, $size--);

    // Recover index from image
    $y   = floor($idx / $W);
    $x   = $idx % $W;
    $idx = imageColorAt($fix, $x, $y);
    $lst = imageColorAt($fix, $size % $W, floor($size / $W));
    $b   = $lst & 0xff; $lst >>= 8;
    $g   = $lst & 0xff; $lst >>= 8;
    $r   = $lst & 0xff;
    imageSetPixel($fix, $x, $y, imageColorAllocate($fix, $r, $g, $b));

    // Whew. Now recover true x and y from new $idx
    $y   = floor($idx / $W);
    $x   = $idx % $W;

    $rgb = imagecolorat($src, $x, $y);
    $pix = imagecolorsforindex($src, $rgb);
    $rgb = imageColorAllocate($new, $pix['red'], $pix['green'], $pix['blue']);
    imageSetPixel($new, $x, $y, $rgb);
}
ImageDestroy($src);

// $new has now exactly $pixels set to the same pixels of $src,
// the rest are undefined (you can fill $new with white beforehand...)
// die("Memory: " . memory_get_peak_usage());
Header("Content-Type: image/png");
ImagePNG($new);