Remove white background from the image and make it transparent using PHP - php

I got this code to do that:
$im = new Imagick("test.jpg");
$im->paintTransparentImage($im->getImageBackgroundColor(), 0, 500);
$im->setImageFormat('png');
$im->writeImage('finish.png');
And this is the result (I added manually pink background to see the problems better):
When I increase the fuzz then more white pixels disappear next to the object but then more white pixels also disappear inside the object.
I tried the same image on a website and the result there is:
Which is pretty perfect. Does someone know how to do that?
In case someone need the original image for testing:
UPDATE:
Adding $im->despeckleimage(); before $im->paintTransparentImage makes a better result:
The only thing needs to be done is fill fill the small empty areas with white pixels. Is there any way to do that?

I obtained an instant solution using the GrabCut Algorithm. I used OpenCV 3 with python to get your desired output. Unfortunately I do not know php nor do I know imagik.
CODE:
import numpy as np
import cv2
img = cv2.imread('Dress.jpg',1)
cv2..imshow('Original image',img)
mask = np.zeros(img.shape[:2],np.uint8)
bgdModel = np.zeros((1,65),np.float64)
fgdModel = np.zeros((1,65),np.float64)
rect = (60,20,325,503)
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
nimg = img*mask2[:,:,np.newaxis]
cv2.imshow("Extracted image",nimg)
cv2.waitKey()
cv2.destroyAllWindows()
I first created a black background using the mask variable.
This is what I obtained.
Visit THIS PAGE for details of this algorithm and the parameters used. You can work this out for masking on a colored background also.
I beleive the same can be tried out with imagik also. Hope this helps :)
EDIT:
This is in response to the edit you made to the question.
The following was the image uploaded by you:
I applied threshold and obtained the following image:
Now I performed 'morphological closing' operation and obtained this:
Finally I masked the image above with the original image you uploaded in the beginning to obtain this:

Related

Does php image creation functions have any color trouble?

I'm using the following snippet: http://www.phpclasses.org/package/4254-PHP-Render-graphical-diagrams-of-hierarchical-trees.html
And I'm adding a png image to each node. If i get it correctly the code used is:
$strSourceImage = imagecreatefrompng($node->image);
imagecopyresampled($this->img, $strSourceImage, $node->x, $node->y, 0, 0, $node->w, $node->h, $this->imgsize[0], $this->imgsize[1]);
But the png image get its colors altered,
This is the original image: http://postimg.org/image/jz4hjej4f/2e34cb9e/
and this is the result when adding it through php: http://postimg.org/image/mzkw9uwlf/0959e1b9/
Got it. The img was being created with imagecreate(), im using now imagecreatetruecolor(), hope this helps someone in the future.

PHP Imagick outline/contour and sketch

I have a problem with getting fine contour of the image.
How to do it with PHP Imagick?
Input image: Imagick wizard
Plan #1 Outline
Get image with (more/less) clear, consistent background (for example: white, red or transparent)
Remove background if it is set
Add outline (specific color)
Remove image inside
Result: http://i57.tinypic.com/2wg91qx.png
Plan #2 Sketch
Get image with (more/less) clear, consistent background (for example: white, red or transparent)
Remove background if it is set
Add sketch effect
Remove image inside
Result: http://i60.tinypic.com/az9vr5.png
PS:
borders and/or shadows didnt' work for me well
There are many ways to outline a picture. Here's one of them that does more or less what you wanted. Note that wizard's picture requires some extra processing. First background isn't fully white (it has some #FEFEFE or alike pixels). Also what is more troubling the upper part of the desk is filled with pure white. So you can either use white pixels after blurring as background (my way) or try to flood fill from the corner with matteFloodfillImage(). However this may leave space between desk legs not transparent.
function drawImage(Imagick $i)
{
$i->setImageFormat("png");
header("Content-Type: image/" . $i->getImageFormat());
echo $i;
exit;
}
$o = new Imagick('wizard.png');
$o->setImageBackgroundColor('white'); // handle tranparent images
$o = $o->flattenImages(); // flatten after setting background
$o->blurImage(5, 30);
$o->whiteThresholdImage( "#F8F8F8" );
$o->blackThresholdImage( "#FFFFFF" );
$o->edgeImage(5);
$o->negateImage(false);
$o->paintTransparentImage($o->getImagePixelColor(0, 0), 0, 2000);
$o->colorizeImage("red", 1);
drawImage($o);
Sketching is a little more complex and I would recommend further reading on IM capabilities http://www.imagemagick.org/Usage/photos/#color-in

cropping an image via a php file

so i have an image that is originally 1696x1696. i want to use a php file to MIME a png file. what i want the php to do is crop the original file and produce a quarter of the image. Later i plan to use $_GET variables to return which quadrant i want, but for testing/debugging, im just aiming to get the top left quadrant.
here's the code:
Header("Content-type:image/png");
$newImg =imagecreatefrompng('test.png');
//manually entered half height and width
$img=imagecreatetruecolor(848,848);
//here is where the bugs keep flawing the image
imagecopyresampled($img,$newImg,0,0,0,0,1696,1696,1696,1696);
imagepng($img);
imagedestroy($img);
this will produce the image (top, left) like it's supposed to, however it adds several smaller resampled images on top of it. no matter how i toy with it, i cant get it right. i've also tried imagecopy() and cant get it right as well. looked up tutorials and i cant seem to find on that helps.
Your code looks fine. The only thing I would change is to use imagecopyresized() instead of imagecopyresampled() in this use case.
Header("Content-type:image/png");
$source = imagecreatefrompng('images/test.png');
// manually entered half height and width
$thumb = imagecreatetruecolor(848,848);
imagecopyresized($thumb, $source, 0, 0, 0, 0, 1696, 1696, 1696, 1696);
imagepng($thumb);
imagedestroy($thumb);
I am guessing that earlier in your tests, you were overwriting your original image. That would explain the...
however it adds several smaller resampled images on top of it...
...part of your experience. Each time you ran the code, you picked up the previously modified file.
ok, so after enough headbanging and hair-tearing out, i decided to just go back to photoshop and overwrite the .png with my original .psd. starting to get somewhere now. i got my quadrant without all the ridiculousness. when i get a better understanding, i might come back and explain where i kept going wrong

PhMagick Crop Function Echoes Convert with Debug Disabled

Right now I'm in the process of switching my site over from one host to another, and phMagick is acting up on the new server. I have a page that allows users to upload an image via ajax, and the server uses phMagick to crop the image, then create a few resized versions and upload them to S3. Right now, this works perfectly except that the convert command used to crop the image is echoed, and the javascript doesn't know how to handle this because it breaks the format of the JSON response.
Here is the relevant part of the server side script:
require_once(BASE_PATH . "/library/phmagick/phmagick.php");
$phmagick = new phMagick( "{$base}{$uncropped}", "{$base}{$cropped}" );
$phmagick->debug = false;
$phmagick->setImageQuality(100);
$phmagick->crop( $dimensions['width'], $dimensions['height'], $dimensions['y'], $dimensions['x'], 'NorthWest' );
//Generate the large
$phmagick->setSource("{$base}{$cropped}");
$phmagick->setDestination("{$base}{$large}");
$phmagick->resize(640, 640);
//Generate the small
$phmagick->setDestination("{$base}{$small}");
$phmagick->resize(220, 220);
//Generate the thumbnail
$phmagick->setDestination("{$base}{$thumbnail}");
$phmagick->resize(100, 100);
As you can see, I have debug set to false, and I'm not echoing anything in there. Here's the output that is messing with my javascript:
convert $snip_path/10001_uncropped.jpg -gravity NorthWest -crop 399x399+71+0 $snip_path/10001_cropped.jpg{$json_response}
Strangely, you can see that I crop the image, then resize it 3 times, but only the crop is output like this. Also, it only outputs the command itself, and nothing like "An error occurred." I don't see anything in the phMagick_crop class that looks like it might be responsible for the message.
What else might this be? I don't see anything in my code, and I don't see anything in the phMagick code. I don't know where else to look.
Nevermind, I'm an idiot. I'm using phMagick on two different sites, so I was inspecting the source of the one that was more convenient. Turns out the two copies weren't identical. At some point someone added an echo $cmd into the crop class to debug it, and forgot to take it out.

How to compress images in CodeIgniter, yet do not change their dimensions?

I have a site where users can upload images. I process these images directly and resize them into 5 additional formats using the CodeIgniter Image Manipulation class. I do this quite efficiently as follow:
I always resize from the previous format, instead of from the original
I resize using an image quality of 90% which about halves the file size of jpegs
The above way of doing things I implemented after advise I got from another question I asked. My test case is a 1.6MB JPEG in RGB mode with a high resolution of 3872 x 2592. For that image, which is kind of borderline case, the resize process in total takes about 2 secs, which is acceptable to me.
Now, only one challenge remains. I want the original file to be compressed using that 90% quality but without resizing it. The idea being that that file too will take half the file size. I figured I could simply resize it to its' current dimensions, but that doesn't seem to do anything to the file or its size. Here's my code, somewhat simplified:
$sourceimage = "test.jpg";
$resize_settings['image_library'] = 'gd2';
$resize_settings['source_image'] = $sourceimage;
$resize_settings['maintain_ratio'] = false;
$resize_settings['quality'] = '90%';
$this->load->library('image_lib', $resize_settings);
$resize_settings['width'] = $imagefile['width'];
$resize_settings['height'] = $imagefile['height'];
$resize_settings['new_image'] = $filename;
$this->image_lib->initialize($resize_settings);
$this->image_lib->resize();
The above code works fine for all formats except the original. I tried debugging into the CI class to see why nothing happens and I noticed that the script detects that the dimensions did not change. Next, it simply makes a copy of that file without processing it at all. I commented that piece of code to force it to resize but now still nothing happens.
Does anybody know how to compress an image (any image, not just jpegs) to 90% using the CI class without changing the dimensions?
I guess you could do something like this:
$original_size = getimagesize('/path/to/original.jpg');
And then set the following options like this:
$resize_settings['width'] = $original_size[0];
$resize_settings['height'] = $original_size[1];
Ok, so that doesn't work due to CI trying to be smart, the way I see it you've three possible options:
Rotate the Image by 360ยบ
Watermark the Image (with a 1x1 Transparent Image)
Do It Yourself
The DIY approach is really simple, I know you don't want to use "custom" functions but take a look:
ImageJPEG(ImageCreateFromString(file_get_contents('/path/to/original.jpg')), '/where/to/save/optimized.jpg', 90);
As you can see, it's even more simpler than using CI.
PS: The snippet above can open any type of image (GIF, PNG and JPEG) and it always saves the image as JPEG with 90% of quality, I believe this is what you're trying to archive.

Categories