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.
Related
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:
I have a PHP script that takes an images, checks type and filesize, then creates 2 resized copies of the master image, all 3 images are saved to the server. I was under the impression everything worked fine. I was testing out script and on one jpg image I got thrown the error "Content Encoding Error" by firefox. Doing some reading suggested this was a Firefox issue but testing in IE and Chrome resulted in similar errors.
The odd thing is that some .jpg files work, others don't. For those that don't work the error is occurring when the script comes to encode the second resized copy as the master, and first copy are outputted to specified folder. I have checked to see that the image itself isn't corrupt after doing some more reading. The only difference I could note between a .jpg that would allow the script to complete fully and one that wouldn't was that, when viewing the properties of the failing one within Windows it appeared to carry more data, such as camera used to, model number, etc.
Does anyone know what might be causing this error to be thrown?
EDIT
Here's the code I'm using.
$imgsrc = imagecreatefromjpeg($file);
imagecopyresampled($thbout,$imgsrc,0,0,0,0,$thbwid,$thbhei,$width,$height);
imagejpeg($thbout,$thbpath,80);
imagedestroy($thbout);
imagecopyresampled($optout,$imgsrc,0,0,0,0,$optwid,$opthei,$width,$height);
imagejpeg($optout,$optpath,80);
imagedestroy($optout);
Having played about a bit tonight I got it working, by switching the code to this. (Switch to create larger file first)
$imgsrc = imagecreatefromjpeg($file);
imagecopyresampled($optout,$imgsrc,0,0,0,0,$optwid,$opthei,$width,$height);
imagejpeg($optout,$optpath,80);
imagedestroy($optout);
imagecopyresampled($thbout,$imgsrc,0,0,0,0,$thbwid,$thbhei,$width,$height);
imagejpeg($thbout,$thbpath,80);
imagedestroy($thbout);
So I guess my new question becomes, why does it behave like this?
I have this PHP script that saves a picture on my website. I would like to, once the picture is saved, rotate the picture by 90 degrees if it's not landscape. This a piece of my script:
$uploadfile = 'path/where/to/save/picture.jpg';
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
//The code under here is not working
if($_GET['landscape'] == false || $_GET['landscape'] == 'false'){
$img = imagecreatefromjpeg($uploadfile);
$newimg = imagerotate($img, 90.0, 0);
imagejpeg($newimg, $uploadfile);
}
//this is code under here is working
$prev = create_preview($filename, $uploadfile, $ext, true);
}
As you can see I move_uploaded_file() and then I have an if statement that if the picture is not landscape (so landscape == false) I rotate it. Then I create a preview of the picture.
If I comment out the if statement that checks the landscape the code WORKS, so it uploads the picture but it's NOT ROTATED as I want and creates a preview. If I let the if uncommented (like in this case) it seems like it's not saved anymore because when I try to visualize it I see nothing. This means that the code flow goes into the if, then something happens and the picture is not visualized anymore. The problem is in the if statement that rotates the picture.
So there is definitely something wrong in the procedure to rotate the picture, but I don't understand exactly what's wrong, I create the image from the location it has been uploaded to, I rotate it using the PHP function and then recreate the image in the same exact location.
Can anyone of you see where I'm getting this wrong?
Thanks,
Masiar
It's a shame you can't see the error messages. I suggest writing a small test page that will "fake" the iPhone side of things and allow you to test by submitting images without using the phone. Or simply write a short script that will open an image, imagerotate() it and save it, and use that for testing.
Also, as gnud points out, the PHP errors may even already be being written out to a server logfile. (Typically, they'll be somewhere like /var/log/apache/..., but figuring out where they are on your box will be more of a question for SuperUser, I guess...)
Having said that, given all you've said, I suspect that the PHP package for the distribution of Linux you're using does not support the (fairly-heavily-edited) PHP "packaged" version of the GD library. See this enhancement request for Ubuntu for some details.
This means that the imagerotate() function that you're using simply doesn't exist. You'd verify this easily if you enabled error reporting and used a test script.
As a workaround, your options are either to find a version of the GD library that you can install on your box to replace the standard one, or perhaps use a function written in PHP to do the rotation manually.
Alternatively, as Eamorr suggests, you could shell out to a command-line tool like ImageMagick (or maybe use ImageMagick via the PECL ImageMagick library, but that's probably overkill for one rotate.)
As an aside, I believe the iPhone specifically "rotates" photos that it's taken (e.g. in landscape orientation) by setting a flag in the image metadata, rather than actually rotating the image data, so if you're rotating images taken on an iPhone, make sure that you test with images taken in both portrait and landscape orientations, and check that your image rotation is doing the right thing in each case.
If I recall correctly, the photo data is always in portrait orientation, and just has the "landscapeness" set in the EXIF orientation data if the photo was taken with the phone held in landscape orientation. There are different values for if the phone's held upside-down, too.
To flip 180 degrees:
exec('mogrify -flip /path/to/your/picture');
You need to install imagemagick
I'm sure you can figure out how to flip it 90 degrees very easily.
I use Soundcloud for my tracks.
I'm using their jquery player to place a widget on my new site, as you can see on the top right:
The problem is, the waveform Souncloud provides is a one colour only deal:
My goal: To change this waveform PNG from curent colour to black, but client side.
I know I can change things using PHPs GD library, and I've done this successfully with a test image on my server using this code:
http://php.net/manual/en/function.imagefilter.php
(Search for "IMG_FILTER_BRIGHTNESS")
<?php
$im = imagecreatefrompng('hello.png');
if($im && imagefilter($im, IMG_FILTER_BRIGHTNESS, -255))
{
echo 'Image brightness changed.';
imagepng($im, 'hello.png');
imagedestroy($im);
}
else
{
echo 'Image brightness change failed.';
}
?>
It works perfectly! BUT
It changes the actual image on my server! Pretty cool, but not possible...
Obviously I cant change the image on Soundcloud's server (all the data, images, music comes from there API)
So What I'm looking for is a way were I can change the colour of the PNG client side, on the fly. I have a lot of tracks on there, so basically each time the user clicks next or previous, the waveform loads in and before it does it needs to change that image's colour :-?
Is this possible?
To see the player in action on my test site
(the styling on that one is old, by the way, but it's functionality is correct)
http://marckremers.com/2011/
NB the entire site does not work beyond what you see there. Still a WIP.
Thanks so much
This would have to be done client-side using Javascript, either a fully JS solution or one that uses AJAX to send it to PHP, then receives the final image.
You can try the Pixastic JS library:
http://www.pixastic.com/lib/docs/#intro
If that doesn't work, I would use jQuery to read the image, send it to a PHP script using JSRS/AJAX and then replace it on the page.
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.