So I want to be able to jumble up an image so as to distort the original image. What I mean is this. Load an image, loop through the image and take 32x32 blocks and store each individual block in an array. Then reassemble them as a new picture with the blocks in random order.
this is the code I have currently to take and store the blocks from original image and then create reassemble the image (Note this doesn't have the randomization part yet). But for some reason it doesn't output correctly.
<?php
$name = "pic.jpg";
$src = imagecreatefromjpeg($name);
list($width, $height, $type, $attr) = getimagesize($name);
$x_size = floor($width/32);
$y_size = floor($height/32);
$mixed = array();
$new_image = imagecreatetruecolor(32,32);
$x = 0;
$y = 0;
for($y = 0; $y < $height; $y+= 32) {
for($x = 0; $x < $width; $x+=32) {
imagecopy($new_image, $src, 0, 0, $x, $y, 32, 32);
array_push($mixed, $new_image);
}
}
$final_image = imagecreatetruecolor($width, $height);
$i = 0;
$x1 = 0;
$y1 = 0;
for($i = 0; $i < sizeof($mixed); $i++) {
$x1++;
if($x1 >= $x_size) {
$x1 = 0;
$y1++;
}
imagecopymerge($final_image, $mixed[$i], $x1, $y1, 0,0,32,32,100);
}
header('Content-Type: image/jpeg');
imagejpeg($final_image);
?>
Original Image:
http://puu.sh/236XS
Output:
http://puu.sh/236YO
If you can help it wouldbe greatly appreciated.
Thanks.
I solved my own question using the following code:
<?php
include("test.php");
//global variables
$name = "pic.jpg";
$size = 64;
$x = 0;
$y = 0;
$spots = array("0,0", "0,1", "0,2", "0,3",
"1,0", "1,1", "1,2", "1,3",
"2,0", "2,1", "2,2", "2,3",
"3,0", "3,1", "3,2", "3,3");
//open image from file (Original image)
$src = imagecreatefromjpeg($name);
//load image details
list($width, $height, $type, $attr) = getimagesize($name);
//calculate amount of tiles on x/y axis.
$x_size = floor($width/$size);
$y_size = floor($height/$size);
$new_image = imagecreatetruecolor($size,$size);
$final_image = imagecreatetruecolor($width, $height);
$used = array();
for($y = 0; $y < $height; $y+= $size) {
for($x = 0; $x < $width; $x+= $size) {
//generate random x/y coordinates
redo:
$spot = rand(0, sizeof($spots)-1);
if(!in_array($spot, $used)) {
$coords = explode(",", $spots[$spot]);
//grab 32x32 square from original image
imagecopy($new_image, $src, 0, 0, $x, $y, $size, $size);
//place 32x32 square into new image at randomly generated coordinates
imagecopy($final_image, $new_image, $coords[0]*$size, $coords[1]*$size, 0,0,$size,$size);
array_push($used, $spot);
} else {
goto redo;
}
}
}
//display final image
header('Content-Type: image/jpeg');
imagejpeg($final_image);
print_r($used);
?>
Might not be the most efficient code, but it works :)
Related
I'm trying to convert a grayscale image to pure black and white in PHP using the GD library.
The purpose would be to detect the cervical cells within the image.
I'll leave the PHP code and a MatLab one (I wrote this code in MatLab and I'm trying to obtain the same result in PHP). Basically, I'm having trouble accessing each individual pixel's color and modifying it. sample image
PHP:
<?php
$im = imagecreatefromjpeg("celule.jpg");
function imagetograyscale($im)
{
if (imageistruecolor($im)) {
imagetruecolortopalette($im, false, 256);
}
for ($c = 0; $c < imagecolorstotal($im); $c++) {
$col = imagecolorsforindex($im, $c);
$gray = round(0.299 * $col['red'] + 0.587 * $col['green'] + 0.114 * $col['blue']);
imagecolorset($im, $c, $gray, $gray, $gray);
}
}
imagetograyscale($im);
//imagefilter($im, IMG_FILTER_CONTRAST, -255); //i'm not looking for this effect
header('Content-type: image/jpeg');
imagejpeg($im);
$C = imagesx($im); //width
$L = imagesy($im); //height
echo "Dimensiuni imagine: latime $C, inaltime $L <br>";
//scanning through the image
for($x = 0; $x < $L; $x++) { //each line
for($y = 0; $y < $C; $y++) { //each column
// pixel color at (x, y)
$color = imagecolorat($im, $y, $x);
$color = imagecolorsforindex($im, $color); //getting rgb values
$RED[$x][$y] = $color["red"]; //each rgb component
$GREEN[$x][$y] = $color["green"];
$BLUE[$x][$y] = $color["blue"];
}
}
?>
MATLAB:
clear all, clc, close all;
I = imread('celule.jpg');
imshow(I)
title('original');
a=rgb2gray(I);
figure;
imshow(a)
title('grayscale');
s=size(a);
for i=1:s(1)
for j=1:s(2)
if a(i,j)>190
a(i,j)=0;
else a(i,j)=255;
end
end
end
figure;
imshow(a)
title('pure black and white');
Here's a way to do that with gd:
#!/usr/bin/php -f
<?php
// Open image and get dimensions
$im = imagecreatefromjpeg("cellule.jpg");
$w = imagesx($im);
$h = imagesy($im);
// Convert to greyscale
imagefilter($im,IMG_FILTER_GRAYSCALE);
imagepng($im, "grey.png"); // DEBUG only
// Allocate a new palette image to hold the b&w output
$out = imagecreate($w,$h);
// Allocate b&w palette entries
$black = imagecolorallocate($out,0,0,0);
$white = imagecolorallocate($out,255,255,255);
// Iterate over all pixels, thresholding to pure b&w
for ($x = 0; $x < $w; $x++) {
for ($y = 0; $y < $h; $y++) {
// Get current color
$index = imagecolorat($im, $x, $y);
$grey = imagecolorsforindex($im, $index)['red'];
// Set pixel white if below threshold - don't bother settting black as image is initially black anyway
if ($grey <= 190) {
imagesetpixel($out,$x,$y,$white);
}
}
}
imagepng($out, "result.png");
?>
I have a script that crops and rotates an image.
But i end up with a black bar in my image:
http://prntscr.com/r9l1w5 (screenshot)
I found a script on the internet, that is able to remove black bars on images. But i am unable to make it work together on 1 page.
(view-image.php) My script:
<?php
$filenamegetter = $_GET['imgid'];
$degree = 0;
// File and rotation
$filename = 'img/' . $filenamegetter . '';
$degrees = $degree;
$percent = 0.30;
// Content type
header('Content-type: image/jpeg');
// Get new sizes
list($width, $height) = getimagesize($filename);
if ($width > "1000") {
$newwidth = $width * $percent;
$newheight = $height * $percent;
} else {
$newwidth = $width;
$newheight = $height;
}
// Load
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromjpeg($filename);
// Rotate
$rotate = imagerotate($source, $degrees, 0);
imagecopyresized($thumb, $rotate, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
imagejpeg($thumb);
// Free the memory
imagedestroy($source);
imagedestroy($thumb);
?>
The anti black bar script i wish it works together with:
<?php
$image_path = "image.jpg";
$jpg = imagecreatefromjpeg($image_path);
$black = array("red" => 0, "green" => 0, "blue" => 0, "alpha" => 0);
$removeLeft = 0;
for($x = 0; $x < imagesx($jpg); $x++) {
for($y = 0; $y < imagesy($jpg); $y++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeLeft += 1;
}
$removeRight = 0;
for($x = imagesx($jpg)-1; $x > 0; $x--) {
for($y = 0; $y < imagesy($jpg); $y++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeRight += 1;
}
$removeTop = 0;
for($y = 0; $y < imagesy($jpg); $y++) {
for($x = 0; $x < imagesx($jpg); $x++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeTop += 1;
}
$removeBottom = 0;
for($y = imagesy($jpg)-1; $y > 0; $y--) {
for($x = 0; $x < imagesx($jpg); $x++) {
if(imagecolorsforindex($jpg, imagecolorat($jpg, $x, $y)) != $black){
break 2;
}
}
$removeBottom += 1;
}
$cropped = imagecreatetruecolor(imagesx($jpg) - ($removeLeft + $removeRight), imagesy($jpg) - ($removeTop + $removeBottom));
imagecopy($cropped, $jpg, 0, 0, $removeLeft, $removeTop, imagesx($cropped), imagesy($cropped));
header("Content-type: image/jpeg");
imagejpeg($cropped); //change to `imagejpeg($cropped, $image_path);` to save
imagedestroy($cropped);
imagedestroy($jpg);
I'd like to know how i can implent the anti black bar script in my script. I tried multiple ways but i end up with a empty page.
For anyone having problems with imagecopyresampled or imagerotate with black bars on background, I have found a code example here:
There are a lot of factors but for me the problem was the new size after rotating the image.
https://qna.habr.com/q/646622#answer_1417035
// get image sizes (X,Y)
$wx = imagesx($imageW);
$wy = imagesy($imageW);
// create a new image from the sizes on transparent canvas
$new = imagecreatetruecolor($wx, $wy);
$transparent = imagecolorallocatealpha($new, 0, 0, 0, 127);
$rotate = imagerotate($imageW, 280, $transparent);
imagealphablending($rotate, true);
imagesavealpha($rotate, true);
// get the newest image X and Y
$ix = imagesx($rotate);
$iy = imagesy($rotate);
//copy the image to the canvas
imagecopyresampled($destImg, $rotate, 940, 2050, 0, 0, $ix, $iy, $ix, $iy);
I'm working on a project where I have to convert some instructions text to images and send them by email.
For testing purpose, I'm trying a simple code to output a converted text as an image on the browser, but it's always returning a small white box like this:
I have GD installed on my server.
Here's my code:
<?php
header("Content-type: image/png");
function drawImage()
{
$width = 0;
$height = 0;
$offset_x = 0;
$offset_y = 0;
$bounds = array();
$image = "";
$msg = "Some Sample Text....";
$font = "ARIAL.TTF";
$size = 24; // default font size.
$rot = 0; // rotation in degrees.
$pad = 0; // padding.
$transparent = 1; // transparency set to on.
$red = 0; // black text...
$grn = 0;
$blu = 0;
$bg_red = 255; // on white background.
$bg_grn = 255;
$bg_blu = 255;
// get the font height.
$bounds = ImageTTFBBox($size, $rot, $font, "W");
if ($rot < 0)
{
$font_height = abs($bounds[7]-$bounds[1]);
}
else if ($rot > 0)
{
$font_height = abs($bounds[1]-$bounds[7]);
}
else
{
$font_height = abs($bounds[7]-$bounds[1]);
}
// determine bounding box.
$bounds = ImageTTFBBox($size, $rot, $font, $msg);
if ($rot < 0)
{
$width = abs($bounds[4]-$bounds[0]);
$height = abs($bounds[3]-$bounds[7]);
$offset_y = $font_height;
$offset_x = 0;
}
else if ($rot > 0)
{
$width = abs($bounds[2]-$bounds[6]);
$height = abs($bounds[1]-$bounds[5]);
$offset_y = abs($bounds[7]-$bounds[5])+$font_height;
$offset_x = abs($bounds[0]-$bounds[6]);
}
else
{
$width = abs($bounds[4]-$bounds[6]);
$height = abs($bounds[7]-$bounds[1]);
$offset_y = $font_height;;
$offset_x = 0;
}
$image = imagecreate($width+($pad*2)+1,$height+($pad*2)+1);
$background = ImageColorAllocate($image, $bg_red, $bg_grn, $bg_blu);
$foreground = ImageColorAllocate($image, $red, $grn, $blu);
if ($transparent) ImageColorTransparent($image, $background);
ImageInterlace($image, false);
// render the image
ImageTTFText($image, $size, $rot, $offset_x+$pad, $offset_y+$pad, $foreground, $font, $msg);
// output PNG object.
imagePNG($image);
}
drawImage();
?>
Is this as simple as changing:
$image = imagereate
to
$image = imagecreate
Looks like a typo to me.
I have the following PHP method that generates new users a profile image when they first sign up, before they upload their own. All it does is just create them a brightly colored square - something to make the interface look a little more interesting when showing a list of users without profile photos.
How could I adapt this method so it created a checkerboard of random colors? Something like this: http://krazydad.com/bestiary/thumbs/random_pixels.jpg
public function generate_random_image($filename, $w = 200, $h = 200, $chosen_color = NULL) {
if(!$chosen_color) {
$color_options = Array("#6f0247", "#FF0569", "#FFF478", "#BAFFC0", "#27DB2D", "#380470", "#9D69D6");
$random = rand(0,sizeof($color_options));
$chosen_color = $color_options[$random];
}
$rgb = self::hex2rgb($chosen_color);
$image = imagecreatetruecolor($w, $h);
for($row = 1; $row <= $h; $row++) {
for($column = 1; $column <= $w; $column++) {
$color = imagecolorallocate ($image, $rgb[0] , $rgb[1], $rgb[2]);
imagesetpixel($image,$column - 1 , $row - 1, $color);
}
$row_count++;
}
$filename = APP_PATH.$filename;
imagepng($image, $filename);
return $chosen_color;
}
How about you just change
$color = imagecolorallocate ($image, $rgb[0] , $rgb[1], $rgb[2]);
to
$color = imagecolorallocate ($image, rand(0,255), rand(0,255), rand(0,255));
Then, each pixel will have it's own colour. Just draw to a small image, then scale by 200% or 300% (or some other arbitrary number) and you'll get nice, big chunky pixels like the image you linked.
While iterating through $rows and $columns you should increase step to desired pixel size and choose another color with each iteration.
example for pixel width = 20x20 :
$pixel = 20;
for($row = 0; $row <= $h / $pixel; $row++) {
for($column = 0; $column <= $w/ $pixel; $column++) {
$rgb = self::hex2rgb($color_options[rand(0,sizeof($color_options))]);
$color = imagecolorallocate ($image, $rgb[0] , $rgb[1], $rgb[2]);
imagefilledrectangle(
$image,
$column*$pixel,
$row*pixel,
$column*$pixel+$pixel,
$row*pixel+$pixel,
$color
);
}
}
i have n-images and want to create one with php code. I use imagecopymerge(), but can't make it. Some example please?
Code:
$numberOfImages = 3;
$x = 940;
$y = 420;
$background = imagecreatetruecolor($x, $y*3);
$firstUrl = '/images/upload/photoalbum/photo/1.jpg';
$secondUrl = '/images/upload/photoalbum/photo/2.jpg';
$thirdUrl = '/images/upload/photoalbum/photo/3.jpg';
$outputImage = $background;
$first = imagecreatefromjpeg($firstUrl);
$second = imagecreatefromjpeg($secondUrl);
$third = imagecreatefromjpeg($thirdUrl);
imagecopymerge($outputImage,$first,0,0,0,0, $x, $y,100);
imagecopymerge($outputImage,$second,0,$y,0,0, $x, $y,100);
imagecopymerge($outputImage,$third,0,$y*2,0,0, $x, $y,100);
imagejpeg($outputImage, APPLICATION_PATH .'/images/upload/photoalbum/photo/test.jpg');
imagedestroy($outputImage);
Thanks kruksmail,
I adapted your answer for a specific project in which the images could be unknown. So I made your answer work with an array of images.
It also gives the ability to specify how many rows or columns you want. I added some comments to help also.
$images = array('/images/upload/photoalbum/photo/1.jpg','/images/upload/photoalbum/photo/2.jpg','/images/upload/photoalbum/photo/3.jpg');
$number_of_images = count($images);
$priority = "columns"; // also "rows"
if($priority == "rows"){
$rows = 3;
$columns = $number_of_images/$rows;
$columns = (int) $columns; // typecast to int. and makes sure grid is even
}else if($priority == "columns"){
$columns = 3;
$rows = $number_of_images/$columns;
$rows = (int) $rows; // typecast to int. and makes sure grid is even
}
$width = 150; // image width
$height = 150; // image height
$background = imagecreatetruecolor(($width*$columns), ($height*$rows)); // setting canvas size
$output_image = $background;
// Creating image objects
$image_objects = array();
for($i = 0; $i < ($rows * $columns); $i++){
$image_objects[$i] = imagecreatefromjpeg($images[$i]);
}
// Merge Images
$step = 0;
for($x = 0; $x < $columns; $x++){
for($y = 0; $y < $rows; $y++){
imagecopymerge($output_image, $image_objects[$step], ($width * $x), ($height * $y), 0, 0, $width, $height, 100);
$step++; // steps through the $image_objects array
}
}
imagejpeg($output_image, 'test.jpg');
imagedestroy($output_image);
print "<div><img src='test.jpg' /></div>";