PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label image-processing. Show all posts
Showing posts with label image-processing. Show all posts

Tuesday, October 11, 2022

[FIXED] How can you find the "majority colors" of an image using PHP?

 October 11, 2022     algorithm, gd, image-processing, imagemagick, php     No comments   

Issue

How can I calculate what the majority colors of an image are in PHP? I'd prefer to group different shades of a similar color into a single bucket, so for example all shades of blue are just counted as "blue".

In other words, I'd like a function that takes an image and returns a simple array similar to:

"blue":90%, "white":10%

No need for high accuracy, just enough to categorize the images by dominant and sub-dominant colors. Thanks!


Solution

Here's one approach:

1) Define a set of colours which we'll call centroids -- these are the middle of the basic colours you want to break images into. You can do this using a clustering algorithm like k-means, for example. So now you've got, say, 100 centroids (buckets, you can think of them as), each of which is an RGB colour triple with a name you can manually attach to it.

2) To generate the histogram for a new image:

  • open the image in gd or whatever
  • convert it to an array of pixel values (e.g. using imagecolorat)
  • determine the distance (euclidean distance is ok) between the pixel value and all the centroids. Classify each pixel as to which bucket it's closest to.
  • Your output is a centroid assignment for each pixel. Or, given you just want a histogram, you can just count how many times each centroid occurs.

Bear in mind that this kind of colour assignment is somewhat subjective. I'm not sure there'll be a definitive mapping from colours to names (e.g., it's language dependent). But if you google, there might exist a look-up table that you could use, although I've not come across one.

Hope this helps!

Ben



Answered By - Ben
Answer Checked By - Katrina (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How do I upload my reformatted image?

 October 11, 2022     gd, image-processing, image-resizing, php     No comments   

Issue

I know this is very close to complete. My aim is to re-size the image a user is uploading by a factor of 0.5. I have achieved in returning the width and height of the image uploaded and have achieved halving those values. Code below:

//get image attributes
    $target = "Images/";
    $target = $target . basename($_FILES['myFile']['name']);

    $thumbnailsize = 0.5;

    //Get uploaded image width and height.
    list($width, $height) = getimagesize($target);

    //Half the current image in size.
    $newWidth = $width * $thumbnailsize;
    $newheight = $height * $thumbnailsize;

    $new_target = imagecreatefromjpeg($target);
    $image = imagecreate($newWidth, $newheight);

    imagecopyresized($image, $new_target, 0, 0, 0, 0, $newWidth, $newheight, $width, $height);

    $pic = $_FILES['myFile']['name'];
    move_uploaded_file($_FILES['myFile']['tmp_name'], $target);

I think I am now going wrong with my variable use and UPDATE SQL statement, see below:

$tUser_SQLselect = "UPDATE User SET imageLocation='" . $pic . "' ";
$tUser_SQLselect .= "WHERE ID = '" . $userID . "' ";

Any advice will appreciated, thanks.


Solution

You're not calling imagejpeg() in there anywhere, so your resized file is not saved anywhere. And unless you're planning on saving the original file alongside the resized one, you cannot use move_uploaded_files() on the copy - m_u_l() exists specifically to apply certain security checks on the uploaded files, so no tampering can occur after the upload completes but before the file's moving around - your resized image would trigger the safety check.

You are also wide-open to SQL injection attacks via that $pic variable - the ['name'] parameter in the $_FILES array is user-supplied data, and can be used to subvert your server.



Answered By - Marc B
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to optimize images in PHP?

 October 11, 2022     gd, image-processing, imagemagick, php     No comments   

Issue

I've a website where users can save their profile image (avatar).

I'd like to make some optimization to the image when they load it.

I mean, it's an avatar image, doesn't need full resolution, nor great size.

What can i do? I've been thinking:

  • Resize it
  • Low the quality

Possible:

  • convert it to GIF
  • Color fill to transparent PNGs

There are some library better (simpler) than GD to do this?

Thanks a lot!


Solution

GD is how this is done. It sounds like a simple operation, but there are a number of factors that you really want to get right if you're going to do this. All in all, this winds up being several hundred lines of code to take care of everything.

My recommendation is that although you may wish to resize an image (which requires a lossy recompression if using JPEG), converting it to a GIF is a bad idea. You don't know what the source type is, so doing that is problematic.

Here's my recommended flow:

1) Resize the image to your output format. You can force a cropping aspect ratio here as well, if you want.

2) Determine original source mode:

  • 8 bit indexed (GIF/PNG8): Save as PNG8 (format tends to be smaller than GIF).
  • 16-24 bit: Save as JPG. Quality is up to you, but 70% is a good baseline.
  • 32 bit (PNG24): Save as PNG24, taking care to maintain the transparency.

Note, this solution pretty much destroys any 'animated' gifs, but... that's what happens when you try to resize an animated gif.

Although... I also highly recommend to NOT do this as a single stage process and removing the original files. This is the kind of thing that will only come back to bite you later.

Disk space is cheap these days... far better to store the original in a high quality format (even at 2K x 2K resolution), then create an image service which will serve the resolution/quality you need and cache the result.



Answered By - John Green
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How do edit animated GIF image with GD?

 October 11, 2022     gd, image-processing, php     No comments   

Issue

I use this function to update an animated GIF image, but GD is rendering it as static?

function draw_image ()

  {

    $img=imagecreatefromgif('images/moni.gif');

    $text='test';
    $lastpayout='test'; 
    $colors['name'] = imagecolorallocate($img, 999, 000, 156);
    ImageTTFText($img, 9, 0, 20, 235, $colors['name'], "images/impact.ttf", $text);
    ImageTTFText($img, 9, 0, 20, 250, $colors['name'],"images/tahoma.ttf",$lastpayout);
    ImageTTFText($img, 10, 0, 15, 270, $colors['name'], "images/tahoma.ttf", $text);
    header("Content-type: image/gif");
    imagegif($img);
  }

echo  draw_image ();

This function converts the animated GIF into a static GIF. Can anyone help me?


Solution

If you can use imagick:

$gif = new Imagick('full/path/to/your/image.gif');

$draw = new ImagickDraw();    
$draw->setFont('full/path/to/your/font.ttf');
$draw->setFontSize(30);
$draw->setFillColor('white');

// put text on each frame
foreach($gif as $frame){
  $gif->annotateImage($draw, $x = 10, $y = 45, $angle = 0, 'Your text');         
}    

header('Content-Type: image/gif');
print $gif->getImagesBlob();


Answered By - nice ass
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why does this basic imagejpeg() resizer returns a black image?

 October 11, 2022     gd, image, image-processing, php, upload     No comments   

Issue

EDIT

Thanks for all your answers, especially @Mailerdaimon who noticed that I wasn't using the computed values in the imagecopyresampled function.

I don't get black images anymore, but i still do get some black part so i figure my ratio formula should be updated : if i upload a landscape image, the height of the new image is smaller than 170px, and then there's some black showing.

How can i make sure the height of the image goes all the way ?


Below is a simple script to allow users upload pictures. Once the upload is done, the pictures are displayed as a 170px(h) x 150px(w) thumbnail.

The resize part does work since the output image is 170x150px BUT i still get some black area if

if ($_SERVER["REQUEST_METHOD"] == "POST") 
{

$maxWidth  = 150;
$maxHeight = 170;

$name = $_FILES ['image'] ['name'];
$type = $_FILES ["image"] ["type"];
$size = $_FILES ["image"] ["size"];
$tmp_name = $_FILES ['image'] ['tmp_name'];
list($originalWidth, $originalHeight) = getimagesize($tmp_name);


 if ($originalWidth > $originalHeight) 
 {
   $thumbnail_height = floor(($originalHeight/$originalWidth)*$maxWidth);
   $thumbnail_width  = $maxWidth;
 } else {
   $thumbnail_width  = floor(($originalWidth/$originalHeight)*$maxHeight);
   $thumbnail_height = $maxHeight;
 }

 // Resample  
  $image_p = imagecreatetruecolor($maxWidth, $maxHeight);
  imagecreatefrompng($tmp_name);
  imagecopyresampled($image_p, 0, 0, 0, 0, $thumbnail_width, $thumbnail_height, 
  $originalWidth, $originalHeight);

//start upload process
$RandomNumber = uniqid();
$location = "uploads/$RandomNumber";
imagejpeg($image_p,  $location, 100);      

$sql=query("UPDATE users SET image = '".$location."' WHERE id = '$id'"); 

        } 
  }

Any idea what I'm doing wrong?


Solution

I never used php, so this might not be correct, but i can´t see where you use your computed values for width and height!

if ($originalWidth > $maxWidth || $originalHeight > $maxHeight)
 {
      if ($originalWidth / $maxWidth > $originalHeight / $maxHeight) 
     {
       // width is the limiting factor
       $width = $maxWidth;
       $height = floor($width * $originalHeight / $originalWidth);

     } else { 
       // height is the limiting factor
       $height = $maxHeight;
       $width = floor($height * $originalWidth / $originalHeight);
     }

here you compute the height and width and after that they dont appear anywhere in your code...

EDIT: You use:

$image_p = imagecreatetruecolor($maxWidth, $maxHeight);
imagecreatefrompng($tmp_name);
imagecopyresampled($image_p, 0, 0, 0, 0, $thumbnail_width, $thumbnail_height,$originalWidth, $originalHeight);

But the Documentation of imagecopyresmapled states that the function takes the follow

imagecopyresampled ($dst_image ,$src_image ,$dst_x ,$dst_y ,$src_x ,$src_y ,$dst_w , $dst_h ,$src_w ,$src_h )

Though i think your code should be

imagecopyresampled($image_p,$tmp_name, 0, 0, 0, 0, $thumbnail_width, $thumbnail_height,$originalWidth, $originalHeight);

as already mentioned by @Manolo Salsas (and several others)

EDIT2: another problems lies in how you compute your Heigth and Width Values. if $height gets computed likes this

$height = floor($width * $originalHeight / $originalWidth);

it can be smaller than $maxHeight, though creating a black (unfilled) area in your Resulting image, as you have created this image using the max values

$image_p = imagecreatetruecolor($maxWidth, $maxHeight);

To fix this use your computed $thumbnail_height and $thumbnail_width values to create the image

 $image_p = imagecreatetruecolor($thumbnail_width, $thumbnail_height);

or always resize your image to the max values

imagecopyresampled($image_p,$tmp_name, 0, 0, 0, 0, $maxWidth, $maxHeight,$originalWidth, $originalHeight);

which may distort the image. If you dont want to distort the image think about resizing first such that on size fits in the thumbnail and then crop the longer side.



Answered By - Mailerdaimon
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, October 10, 2022

[FIXED] How to calculate thickness of an object in PNG file using PHP GD library

 October 10, 2022     gd, image-processing, php, php-gd, png     No comments   

Issue

I have a PNG frame and I want to know its thickness. I am able to calculate the width/height of the image itself.

$frame = imagecreatefrompng('frame.png');
// get frame dimentions
$frame_width = imagesx($frame);
$frame_height = imagesy($frame);

But can't figure out a way to calculate thickness of frame, please see image below so see what I mean.

enter image description here

Any suggestions?


Solution

From the last answer it shows that there's no objects in a raster image file. However, you can do it by searching the first occurrence of transparent colour and the first occurrence of the non-transparent colour and calculate the distance of them (assumes that your image's blank area are all transparent).

Example code:

<?php
$img = imagecreatefrompng('./frame.png');//open the image
$w = imagesx($img);//the width
$h = imagesy($img);//the height

$nonTransparentPos = null;//the first non-transparent pixel's position
$transparentPos = null;//the first transparent pixel's position

//loop through each pixel
for($x = 0; $x < $w; $x++){
   for($y = 0; $y < $h; $y++){
        $color = imagecolorsforindex($img,imagecolorat($img,$x,$y));
        if($color['alpha'] < 127 && $nonTransparentPos === null){
            $nonTransparentPos = array($x,$y);
        }
        if($color['alpha'] === 127 && $transparentPos === null){
            $transparentPos = array($x,$y);
        }
   }
   //leave the loop if we have finished finding the two values.
   if($transparentPos !== null && $nonTransparentPos !== null){
        break;
   }
}
$length = $transparentPos[0]-$nonTransparentPos[0];//calculate the two point's x-axis distance
echo $length;
?>


Answered By - Licson
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to flip text vertically/horizontally using php?

 October 10, 2022     flip, gd, image-processing, php, text     No comments   

Issue

Does anyone know how to achieve this?


Solution

I am assuming from your tags that you mean to flip a GD image.

Do you mean flip as in rotate? That can be done using imagerotate:

Rotates the image image using the given angle in degrees.

The center of rotation is the center of the image, and the rotated image may have different dimensions than the original image.

Or do you mean mirror an image? There's no method for that out of the box, but maybe this code snippet helps. (It not very performant, though, because it copies pixel by pixel.)

For fast advanced image editing operations, ImageMagick is the best tool around. If you are on shared hosting, it needs to be installed by your provider to work.



Answered By - Pekka
Answer Checked By - Marie Seifert (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I replace one color with another in a png 24 alpha transparent image with GD

 October 10, 2022     gd, image-processing, php     No comments   

Issue

I have tried:

$index = imagecolorresolve ( $im,  0,0,0 ); // get black
imagecolorset($im, $index, 255, 0, 255); // SET NEW COLOR

This seems to work with png 8 but not 24, and if I do it with 8 it turns out all weird because of the anti-aliasing.

Here is the full test code I'm using. (this is just test code, so be gentle).

function LoadPNG($imgname, $color = false)
{        
    $im = @imagecreatefrompng($imgname);
    imagealphablending($im, false); 

    if($color) {
      $index = imagecolorresolve ( $im,  0,0,0 ); // get black
      imagecolorset($im, $index, 255, 0, 255); // SET NEW COLOR
    }

    imageAlphaBlending($im, true);
    imageSaveAlpha($im, true);

    return $im;
}

header('Content-Type: image/png');

$img = LoadPNG("head.png", "red");

imagepng($img);
imagedestroy($img);

Solution

You can try the following:

  • cycle all points
  • get the color of that point
  • if it matches your colorA, set that pixel to the desired colorB

Code:

for ($x=imagesx($im); $x--; ) {
    for ($y=imagesy($im); $y--; ) {
        $c = imagecolorat($im, $x, $y);
        if ($c[0] == 0 && $c[1] == 0 && $c[2] == 0) {
            // here we use the new color, but the original alpha channel
            $colorB = imagecolorallocatealpha($im, 255, 0, 255, $c[3]);
            imagesetpixel($im, $x, $y, $colorB);
        }
    }
}

Hope this helps!



Answered By - aorcsik
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] What kind of image processing facebook using in http://fb.com/supportdigitalindia

 October 10, 2022     gd, image-processing, php     No comments   

Issue

This is a generated image from fb.com/supportdigitalindia

How Can i create this kind of image . Can I Do it with PHP ?

I need the way to process this kind of images ..


Solution

You can use imagecopymerge() like:

function overlay($img_a, $img_b, $alpha, $output)
{
    $canvas_a = imagecreatefromjpeg($img_a);
    $canvas_b = imagecreatefromjpeg($img_b);

    list($over_w, $over_h) = getimagesize($img_a);
    list($out_w, $out_h) = getimagesize($img_b);

    imagecopymerge(
        $canvas_b,               // Dest
        $canvas_a,               // Src
        0,                       // dst_x
        0,                       // dst_y
        (($over_w-$out_w)/2),    // src_x
        (($over_h-$out_h)/2),    // src_y
        $out_w,                  // src_w
        $out_h,                  // src_h
        100*$alpha               // pct
    );

    imagejpeg($canvas_b, $output, 100);
}

overlay('x.jpg', 'y.jpg', 0.6, 'z.jpg');

This will overlay img_1 on top of img_2 with the alpha specified.



Answered By - Omran Jamal
Answer Checked By - Clifford M. (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to have a function like color overlay with color blend mode without using ImageMagick

 October 10, 2022     gd, image-processing, php     No comments   

Issue

I want to manipulate an image using php only with the result like the color blend mode in photoshop. I hope you can help me.

I have this code but it returns an image that is like a screen blend mode.

<?php
$img="text.png";
$to="";
$bool="";
$imres=$img;

if(isset($_POST['submit'])){
    $im = imagecreatefrompng('text.png');
    // $from=$_POST['oldhex'];

    $to=$_POST['newhex'];
    //conversion of hex to rgb values

    // Get width and height
    // $w = imagesx($im); 
    // $h = imagesy($im);
    // $im= imagecreatetruecolor($w,$h);



    ![enter image description here][1]$r = hexdec(substr($to, 0, 2));
    $g = hexdec(substr($to, 2, 2));
    $b = hexdec(substr($to, 4, 2));
    /* R, G, B, so 0, 255, 0 is green */

    if($im && imagefilter($im, IMG_FILTER_COLORIZE, $r, $g, $b,30)&& imagealphablending($im, true)){// echo 'Image successfully shaded';


        imagepng($im, '5.png');
        $bool="true";
        $imres="5.png";
    }
    else{
        echo 'shading failed.';
    }
}
?>

This is the input image

enter image description here

This is the image that I get...

failed image

This is the image that i want to haveenter image description here


Solution

I have had a try at this and got somethimng fairly similar to what you want - maybe it will give you some ideas for further experimentation. Basically I create another image the same size as yours and fill it with a colour wash and transparency and then blend them.

#!/usr/bin/php
<?php

    $im = imagecreatefrompng('text.png');

    $to='FFCC33';
    //conversion of hex to rgb values

    $r = hexdec(substr($to, 0, 2));
    $g = hexdec(substr($to, 2, 2));
    $b = hexdec(substr($to, 4, 2));

    $wash=imagecreatetruecolor(225,225);
    $col = imagecolorallocatealpha($wash,$r,$g,$b,70);
    imagefill($wash,0,0,$col);

    imagelayereffect($im,IMG_EFFECT_ALPHABLEND);
    imagecopy($im,$wash,0,0,0,0,225,225);
    imagepng($im,'5.png');
?>


Answered By - Mark Setchell
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] What is wrong with my bilinear interpolation algorithm?

 October 10, 2022     algorithm, bilinear-interpolation, gd, image-processing, php     No comments   

Issue

I am using PHP to test out my bilinear algorithm. The code is un-optimized for clarity.

Here is what the code below is doing:

  1. Plot the original pixels from the 2x2 image to the 10x10 destination image. These will leave blank pixels.

Note: The images here are resized from 10x10 to 100x100 for better viewing.

resized

  1. Interpolate the row of pixels.

enter image description here

  1. Interpolate the remaining pixels going from left to right, top to bottom using the row of pixels in step 2:

enter image description here

However, it does not match the result I get in Photoshop using bilinear resampling:

enter image description here

Full source code:

<?php
$image1 = imagecreatefrompng( 'test.png' );

$w1 = imagesx( $image1 );
$h1 = imagesy( $image1 );

$w2 = 10;
$h2 = 10;
$image2 = imagecreatetruecolor( $w2, $h2 );

imagefill($image2, 0, 0, imagecolorallocate($image2, 0x4c, 0x4c, 0x8e)); // added bg for pixels to stand-out

function lerp($v0, $v1, $t) {
    return $v0 + $t*($v1-$v0);
}

function getPixel($image, $x, $y){
    $rgb = imagecolorat( $image, $x, $y );
    $r     = ($rgb >> 16) & 0xFF;
    $g     = ($rgb >> 8) & 0xFF;
    $b     = $rgb & 0xFF;
    return array($r,$g,$b);
}

$maxY1 = $h1 - 1;
$maxX1 = $w1 - 1;
$maxY2 = $h2 - 1;
$maxX2 = $w2 - 1;

// plot original pixels from source to destination
for($y = 0; $y <= $maxY1; $y++) { // loop thru src height

    $newY = floor(($y/$maxY1) * $maxY2);

    for ($x = 0; $x <= $maxX1; $x++) { // loop thru src width

        $newX = floor(($x/$maxX1) * $maxX2);
        $rgb = imagecolorat( $image1, $x, $y );
        $r1     = ($rgb >> 16) & 0xFF;
        $g1     = ($rgb >> 8) & 0xFF;
        $b1     = $rgb & 0xFF;

        imagesetpixel( $image2, $newX, $newY, imagecolorallocate( $image2, $r1, $g1, $b1 ) );

    }
}
imagepng( $image2, 'out1.png' );

// interpolate pixels from pixel[1,0] to pixel[8,0]
$y = 0;
$rgb = imagecolorat( $image2, 0, $y );
$r0     = ($rgb >> 16) & 0xFF;
$g0     = ($rgb >> 8) & 0xFF;
$b0     = $rgb & 0xFF;

$rgb = imagecolorat( $image2, 9, $y );
$r1     = ($rgb >> 16) & 0xFF;
$g1     = ($rgb >> 8) & 0xFF;
$b1     = $rgb & 0xFF;
for($x=1; $x <= 8; $x++){
    $t = $x / 9;
    $r = lerp($r0, $r1, $t);
    $g = lerp($g0, $g1, $t);
    $b = lerp($b0, $b1, $t);
    imagesetpixel( $image2, $x, $y, imagecolorallocate( $image2, $r, $g, $b ) );
}
imagepng( $image2, 'out2.png' );

// interpolate pixels from pixel[1,9] to pixel[8,9]
$y = 9;
$rgb = imagecolorat( $image2, 0, $y );
$r0     = ($rgb >> 16) & 0xFF;
$g0     = ($rgb >> 8) & 0xFF;
$b0     = $rgb & 0xFF;

$rgb = imagecolorat( $image2, 9, $y );
$r1     = ($rgb >> 16) & 0xFF;
$g1     = ($rgb >> 8) & 0xFF;
$b1     = $rgb & 0xFF;

for($x=1; $x <= 8; $x++){
    $t = $x / 9;
    $r = lerp($r0, $r1, $t);
    $g = lerp($g0, $g1, $t);
    $b = lerp($b0, $b1, $t);
    imagesetpixel( $image2, $x, $y, imagecolorallocate( $image2, $r, $g, $b ) );
}
imagepng( $image2, 'out3.png' );

// interpolate remaining pixels
for($x=0; $x <= 9; $x++){
    $rgb = imagecolorat( $image2, $x, 0 );
    $r0     = ($rgb >> 16) & 0xFF;
    $g0     = ($rgb >> 8) & 0xFF;
    $b0     = $rgb & 0xFF;

    $rgb = imagecolorat( $image2, $x, 9 );
    $r1     = ($rgb >> 16) & 0xFF;
    $g1     = ($rgb >> 8) & 0xFF;
    $b1     = $rgb & 0xFF;
    for($y = 1; $y <= 8; $y++){
        $t = $y / 9;
        $r = lerp($r0, $r1, $t);
        $g = lerp($g0, $g1, $t);
        $b = lerp($b0, $b1, $t);
        imagesetpixel( $image2, $x, $y, imagecolorallocate( $image2, $r, $g, $b ) );
    }
}
imagepng( $image2, 'out4.png' );

header('Content-type: image/png');
imagepng( $image2);
imagedestroy( $image1 );

What am I missing?


Solution

Photoshop is correct. In your version the original 4 pixel values end up in the extreme corners of the new image but in the correct bilinear interpolation they end up in the centers of 4 quadrants of the new image. There is no information beyond the edge of the original image so photoshop does constant extrapolation at the edge:

2x2:

enter image description here

10x10 before interpolation:

enter image description here

If you started with a 3x3 image instead of 2x2, your method would cause the original edge pixels to have a diminished contribution to the final image relative to the center pixels, biasing the result.



Answered By - atb
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How can I brighten/darken an image in PHP?

 October 10, 2022     gd, image, image-processing, php     No comments   

Issue

I guess I should be able to use GD to brighten or darken an image in PHP but don't find any info on it. Isn't that possible?


Solution

You can use the imagefilter function provided by PHP5 and up.

bool imagefilter ( resource $image , int $filtertype [, int $arg1 [, int $arg2 [, int $arg3 [, int $arg4 ]]]] )

You should be using the IMG_FILTER_BRIGHTNESS with a value from -255 to 255 to brighten/darken the image.

PHP Manual

Example from the manual

<?php
$im = imagecreatefrompng('sean.png');

if($im && imagefilter($im, IMG_FILTER_BRIGHTNESS, 20))
{
    echo 'Image brightness changed.';

    imagepng($im, 'sean.png');
    imagedestroy($im);
}
else
{
    echo 'Image brightness change failed.';
}
?>


Answered By - Murf
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to make tiled image frame without using exec function?

 October 10, 2022     gd, image-processing, imagemagick, imagick, php     No comments   

Issue

Original image: Original image Here what i need: Here what i need It should be created from this small tile: It should be created from this small tile

A lot of people suggest to use ImageMagick solution (it using php exec function) - http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=21867:

convert frame_template.gif \
-tile blackthin_top.gif -draw 'color 1,0 floodfill' -rotate 90 \
-tile blackthin_btm.gif -draw 'color 1,0 floodfill' -rotate 90 \
-tile blackthin_top.gif -draw 'color 1,0 floodfill' -rotate 90 \
-tile blackthin_btm.gif -draw 'color 1,0 floodfill' -rotate 90 \
-gravity center thumbnail.gif -composite frame_filled.gif

or

PICFrame solution (it using php exec function) - http://www.fmwconcepts.com/imagemagick/picframe/index.php:

picframe [-f frameid] [-m mattesize] [-c mattecolor] [-b bordersize] [-s shade] [-a adjust] [-o opacity ] [-d distance] infile outfile

PHP imagick has great ability to create color borders with:

$imagick = new \Imagick('image.jpg');
$imagick->scaleImage(300, 300, false);

// Create frame placeholder
$imagick->frameimage( 'red','30','30', 30, 0);

// Flood fill with color
$imagick->floodFillPaintImage('green', 10, '#6e0000',0, 0,false
);

header("Content-Type: image/jpg");
echo $imagick->getImageBlob();

But PHP imagick can't use your own image tile to create frame, only solid colors. Here is very related question - How to flood fill the frame with a pattern image using imagick php class?

Another good solution from - https://stackoverflow.com/a/28778953/2337706 but it creates image from big PNG frames and you should know correct image size.

I know that i can create it with php GD - http://php.net/manual/en/ref.image.php but i don't know correct way how implement it this way.


Solution

In ImageMagick, you could just do something simple like this:

convert a1Wit.jpg -mattecolor black -frame 10x10+3+3 -gravity west -chop 3x0 -bordercolor gold -border 3 frame_result.jpg

enter image description here

These commands should be easy enough to translate into Imagick. See http://us3.php.net/manual/en/imagick.frameimage.php and http://us3.php.net/manual/en/imagick.chopimage.php and http://us3.php.net/manual/en/imagick.borderimage.php

Or simply:

convert a1Wit.jpg -bordercolor black -border 7 -bordercolor "gray(35%)" -border 3 -bordercolor "#D0A456" -border 3 frame_result2.jpg

enter image description here

Or

convert a1Wit.jpg -mattecolor "gray(30%)" -frame 13x13+5+5 -gravity northwest -shave 5x5 -bordercolor "#D0A456" -border 3 frame_result3.jpg

enter image description here

Or

convert a1Wit.jpg -mattecolor "gray(30%)" -frame 13x13+5+5 -gravity northwest -bordercolor "#D0A456" -border 3 frame_result4.jpg

enter image description here

Adjust the color thicknesses as desired



Answered By - fmw42
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why do images saved to file differ in size from resources with imagejpeg()?

 October 10, 2022     compression, gd, image, image-processing, php     No comments   

Issue

I'm generating thumbnails from images automatically with the PHP GD library.
I then save the resized image to a file using imagejpeg() with 95% quality.

When I output this file using echo file_get_contents($file), the filesize of the image is always about 2.5 - 4 times as large compared to when I directly output the resized image to the browser using imagejpeg($resource_handle).

Google PageSpeed also tells me images could be compressed by 75%, which confirms the 1/4 ratio noticed.

What could be the reason for this?


Solution

I found the manual (http://php.net/manual/en/function.imagejpeg.php) mentions that the default (without passing the quality argument) quality setting is around 75%.

This explains why outputting an image directly without any other arguments passed to imagejpeg() results in a smaller image then when setting a quality higher than 75 manually.



Answered By - Bastiaan ten Klooster
Answer Checked By - Willingham (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to check if a GIF has transparency using GD?

 October 10, 2022     gd, image-processing, php, php-gd     No comments   

Issue

I saw this thread and the solutions perfectly works but for PNG only. Is there a solution for checking if a GIF image has transparency in PHP-GD?


Solution

I am less familiar with GIFs than other formats, so my assumptions may be incorrect. Please let me know if I am wrong - a simple comment, rather than a down-vote, would be appreciated.

I am assuming that:

  • all GIFs are palettised,
  • the alpha component will be non-zero (probably 127) for any palette entry which is transparent,
  • encoders do not add transparent palette entries unnecessarily.

On that basis, the following code will load a GIF and check that no palette entry contains transparency - rather than checking every single pixel in a very slow double loop over height and width of an image:

<?php

function GIFcontainstransparency($fname){

   // Load up the image
   $src=imagecreatefromgif($fname);

   // Check image is palettised
   if(imageistruecolor($src)){
      fwrite(STDERR,"ERROR: Unexpectedly got a truecolour (non-palettised) GIF!");
   }

   // Get number of colours - i.e. number of entries in palette
   $ncolours=imagecolorstotal($src);

   // Check palette for any transparent colours rather than all pixels - to speed it up
   for($index=0;$index<$ncolours;$index++){
      $rgba = imagecolorsforindex($src,$index);
      if($rgba['alpha']>0){
         return true;
      }
   }
   return false;
}

////////////////////////////////////////////////////////////////////////////////
// main
////////////////////////////////////////////////////////////////////////////////

   if(GIFcontainstransparency("image.gif")){
      echo "Contains transparency";
   } else {
      echo "Is fully opaque";
   }
?>


Answered By - Mark Setchell
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] What is wrong with this code on Sobel filter?

 October 10, 2022     gd, image-processing, php, sobel     No comments   

Issue

I am trying to implement a sobel filter in PHP GD but something is wrong with my code:

$gd = imagecreatefrompng('base.png');
$width = imagesx($gd);
$height = imagesx($gd);

for($i=1; $i<$width-1;$i++){
    for($j=1;$j<$height-1; $j++){
        $pixelMatrix[0][0]= getColor($gd, $i-1,$j-1);
        $pixelMatrix[0][1]= getColor($gd, $i-1,$j);
        $pixelMatrix[0][2]= getColor($gd, $i-1,$j+1);
        $pixelMatrix[1][0]= getColor($gd, $i,$j-1);
        $pixelMatrix[1][2]= getColor($gd, $i,$j+1);
        $pixelMatrix[2][0]= getColor($gd, $i+1,$j-1);
        $pixelMatrix[2][1]= getColor($gd, $i+1,$j);
        $pixelMatrix[2][2]= getColor($gd, $i+1,$j+1);

        $edge=(int) convolution($pixelMatrix);
        if($edge>255) $edge = 255;
        imagesetpixel($gd, $i, $j, imagecolorallocate($gd,$edge,$edge,$edge));
    }

}

function getColor($gd, $x, $y){
    $rgb = @imagecolorat($gd, $x, $y);
    $r = ($rgb >> 16) & 0xFF;
    $g = ($rgb >> 8) & 0xFF;
    $b = $rgb & 0xFF;
    return round($r * 0.3 + $g * 0.59 + $b * 0.11); // gray
}

function convolution($pixelMatrix){

    $gy=($pixelMatrix[0][0]*-1)+($pixelMatrix[0][1]*-2)+($pixelMatrix[0][2]*-1)+($pixelMatrix[2][0])+($pixelMatrix[2][1]*2)+($pixelMatrix[2][2]*1);
    $gx=($pixelMatrix[0][0])+($pixelMatrix[0][2]*-1)+($pixelMatrix[1][0]*2)+($pixelMatrix[1][2]*-2)+($pixelMatrix[2][0])+($pixelMatrix[2][2]*-1);
    return sqrt(pow($gy,2)+pow($gx,2));

}


// send PNG to browser
header("Content-type: image/png");
imagepng($gd);

Base image:

enter image description here

Correct result image:

enter image description here

My result:

enter image description here

For this image the edge contains an int from 0-990 so I limit it to 255. If i remove the cap all I get is noise. Im guessing the error is in translating the edge into RGB values (I dont understand that part) in imagesetpixel, no?


Solution

There are a few things wrong, as marked up in comments, but the bulk of your code is pretty correct.

Main things are:

  • Input image may be palettised, so make true colour
  • Cannot do Sobel in place - you need output image
  • You have a typo where obtaining the height

And that is mainly it, I think!

$gd = imagecreatefrompng('base.png');
imagepalettetotruecolor($gd);        // IN CASE PALETTISED
$width = imagesx($gd);
$height = imagesy($gd);              // NOT imagesx()
$result=imagecreatetruecolor($width,$height); // CREATE OUTPUT IMAGE

for($i=1; $i<$width-1;$i++){
    for($j=1;$j<$height-1; $j++){
        $pixelMatrix[0][0]= getColor($gd, $i-1,$j-1);
        $pixelMatrix[0][1]= getColor($gd, $i-1,$j);
        $pixelMatrix[0][2]= getColor($gd, $i-1,$j+1);
        $pixelMatrix[1][0]= getColor($gd, $i,$j-1);
        $pixelMatrix[1][2]= getColor($gd, $i,$j+1);
        $pixelMatrix[2][0]= getColor($gd, $i+1,$j-1);
        $pixelMatrix[2][1]= getColor($gd, $i+1,$j);
        $pixelMatrix[2][2]= getColor($gd, $i+1,$j+1);

        $edge=(int) convolution($pixelMatrix);
        if($edge>255) $edge = 255;
        imagesetpixel($result, $i, $j, imagecolorallocate($result,$edge,$edge,$edge));
    }
}

imagepng($result,"result.png");

function getColor($gd, $x, $y){
    $rgb = @imagecolorat($gd, $x, $y);
    $r = ($rgb >> 16) & 0xFF;
    $g = ($rgb >> 8) & 0xFF;
    $b = $rgb & 0xFF;
    return round($r * 0.3 + $g * 0.59 + $b * 0.11); // gray
}

function convolution($pixelMatrix){

    $gy=($pixelMatrix[0][0]*-1)+($pixelMatrix[0][1]*-2)+($pixelMatrix[0][2]*-1)+($pixelMatrix[2][0])+($pixelMatrix[2][1]*2)+($pixelMatrix[2][2]*1);
    $gx=($pixelMatrix[0][0])+($pixelMatrix[0][2]*-1)+($pixelMatrix[1][0]*2)+($pixelMatrix[1][2]*-2)+($pixelMatrix[2][0])+($pixelMatrix[2][2]*-1);
    return sqrt(pow($gy,2)+pow($gx,2));

}

enter image description here



Answered By - Mark Setchell
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to check if an image has transparency using GD?

 October 10, 2022     gd, image-processing, php     No comments   

Issue

How do I check if an image has transparent pixels with php's GD library?


Solution

It doesn't look like you can detect transparency at a glance.

The comments on the imagecolorat manual page suggest that the resulting integer when working with a true-color image can actually be shifted four times total, with the fourth being the alpha channel (the other three being red, green and blue). Therefore, given any pixel location at $x and $y, you can detect alpha using:

$rgba = imagecolorat($im,$x,$y);
$alpha = ($rgba & 0x7F000000) >> 24;
$red = ($rgba & 0xFF0000) >> 16;
$green = ($rgba & 0x00FF00) >> 8;
$blue = ($rgba & 0x0000FF);

An $alpha of 127 is apparently completely transparent, while zero is completely opaque.

Unfortunately you might need to process every single pixel in the image just to find one that is transparent, and then this only works with true-color images. Otherwise imagecolorat returns a color index, which you must then look up using imagecolorsforindex, which actually returns an array with an alpha value.



Answered By - Charles
Answer Checked By - Mildred Charles (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Sunday, October 9, 2022

[FIXED] How I can apply color threshold into an image created from `imagecreatefromstring`?

 October 09, 2022     gd, image-processing, php     No comments   

Issue

I have the following piece of code:

define(RED_THESHOLD,100);
define(GREEN_THESHOLD,200);
define(BLUE_THESHOLD,100);

function thresholdImage(String $imgdata){
   $original_limit = ini_get('memory_limit');
   ini_set('memory_limit', '-1');
   $imageResource = imagecreatefromstring($imgData);

   // Limit red green and blue color channels here
}

But I do not know how I can apply the color the constants:

  • RED_THESHOLD
  • GREEN_THESHOLD
  • BLUE_THESHOLD

According to the classic algorithms I need to read pixel by pixel each channel and apply the threshold by the following piece of code (I use images red channel as an example):

 $new_pixel_value = ($red_pixel_value>RED_THESHOLD)?RED_THESHOLD:$red_pixel_value;

Do you know how I can do this?


Solution

This can be done by finding the color index for each pixel, converting that into RGBA, then constraining those values, converting it back into a color index and setting the pixel.

<?php

const RED_THESHOLD = 255;
const GREEN_THESHOLD = 10;
const BLUE_THESHOLD = 10;

$image = imagecreatefrompng('test.png');

$maxX = imagesx($image);
$maxY = imagesy($image);

for ($y = 0; $y < $maxY; ++$y) {
    for ($x = 0; $x < $maxX; ++$x) {
        $existing = imagecolorsforindex($image, imagecolorat($image, $x, $y));

        $red = ($existing['red'] > RED_THESHOLD) ? RED_THESHOLD : $existing['red'];
        $green = ($existing['green'] > GREEN_THESHOLD) ? GREEN_THESHOLD : $existing['green'];
        $blue = ($existing['blue'] > BLUE_THESHOLD) ? BLUE_THESHOLD : $existing['blue'];

        $new = imagecolorexact($image, $red, $green, $blue);

        imagesetpixel($image, $x, $y, $new);
    }
}

imagepng($image, 'test2.png');

Here is a comparison picture: A picture of a rainbow with the above code applied and the output next to it



Answered By - Jacob Mulquin
Answer Checked By - David Goodson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, October 7, 2022

[FIXED] How to estimate standard deviation in images with speckle noise?

 October 07, 2022     image-processing, math, noise, python, statistics     No comments   

Issue

I am using this function that I found on the web, to add speckle noise to images for research purposes:

def add_speckle(k,theta,img):
  
  gauss = np.random.gamma(k, theta, img.size)
  gauss = gauss.reshape(img.shape[0], img.shape[1], img.shape[2]).astype('uint8')
  noise = img + img * gauss 
  return noise

My issue is that I want to estimate/define the speckle noise I add as a standard deviation(sigma) parameter, and this function that I found depends on the gamma distribution or random.gamma() which it depends on the k,theta(shape,scale) parameters, which you can see in the gamma pdf equation down below:

enter image description here

according to my knowledge, the variance can be calculated in gamma distribution as follows:

enter image description here

so standard deviation or sigma is equivalent to:

enter image description here

I want to add speckle noise as sigma dependent, so am saying there should be a way to estimate that sigma from k,theta(shape,scale) that we make the input with, so the speckle_adding() function would look like something like this:

def add_speckle(sigma,img):

edited : for the answer in the comments :

def add_speckle(sigma,mean,img):

  theta = sigma ** 2 / mean
  k = mean / theta
  gauss = np.random.gamma(k,theta,img.size)
  gauss = gauss.reshape(img.shape[0],img.shape[1],img.shape[2]).astype('uint8')
  noise = img + img * gauss 
  print("k=",k)
  print("theta=",theta)
  return noise
  img = cv2.imread('/content/Hand.jpeg')
cv2.imwrite('speckle12.jpg',add_speckle(8,3,img))

thanks sir for your help, but i really understand why k,theta values changes each time i change values of mean while sigma is constant, i think it must not changes??


Solution

As you have noticed that sigma = k ** 0.5 * theta, there are infinite possibilities for parameters in the gamma distribution if only sigma is given (eg. if sigma is 1, (k, theta) can be (1,1) or (4, 0.5) and so on).

If you really want to generate the speckle with statistical inferences as input, I suggest you to add mean as the second input so that the required (k, theta) can be calculated.

The first moment (ie. mean) of a gamma distribution is simply k * theta.

Example:

def add_speckle(mean, sigma, img):
    # find theta
    theta = sigma ** 2 / mean
    k = mean / theta
    
    # your code proceeds...


Answered By - tyson.wu
Answer Checked By - David Goodson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, September 19, 2022

[FIXED] What is difference between setImageCompressionQuality vs setCompressionQuality - Imagick

 September 19, 2022     image, image-processing, imagemagick, imagick, php     No comments   

Issue

I found two methods in Imagick for set image compression quality

A ) setImageCompressionQuality

B ) setCompressionQuality

so I want to know which one is best and why in below condition

I read that setCompressionQuality method only works for new images (?)

I am trying to compress a file jpeg/png

$im = new Imagick();

$im->readImage($file); // path/to/file
$im->setImageCompressionQuality($quality); // 90,80,70 e.g.

$im->writeImage($file);

Solution

The method setImageCompressionQuality sets compression quality for your current image. This method is a wrapper for MagickWand's MagickSetImageCompressionQuality function. Source code is:

WandExport MagickBooleanType MagickSetImageCompressionQuality(MagickWand *wand,
  const size_t quality)
{
  assert(wand != (MagickWand *) NULL);
  assert(wand->signature == MagickWandSignature);
  if (wand->debug != MagickFalse)
    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
  if (wand->images == (Image *) NULL)
    ThrowWandException(WandError,"ContainsNoImages",wand->name);

  //This line sets the quality for the instance 'images'  
  wand->images->quality=quality;
  return(MagickTrue);
}

The method setCompressionQuality sets compression quality for the whole object. This method is a wrapper for MagickWand's MagickSetCompressionQuality function. Source code is:

WandExport MagickBooleanType MagickSetCompressionQuality(MagickWand *wand,
  const size_t quality)
{
  assert(wand != (MagickWand *) NULL);
  assert(wand->signature == MagickWandSignature);
  if (wand->debug != MagickFalse)
    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);

  //This line sets quality for the image_info struct instance.
  wand->image_info->quality=quality;
  return(MagickTrue);
}

The MagickWand struct holds instances of Image and ImageInfo structs, source:

struct _MagickWand
{
  ...

  Image
    *images;          /* The images in this wand - also the current image */

  ImageInfo
    *image_info;      /* Global settings used for images in Wand */
  ...
};

Both Image and ImageInfo structs hold a size_t quality; data member. So for your example setImageCompressionQuality is perfectly fine.



Answered By - zindarod
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing