I need to create an image on the fly where one large image covers a small image. The large image is a mask which makes the underlying image visible. Here is a quick sketch of what I'm trying to accomplish:
enter image description here
It's important that Y lies beneath X.
I have created to code for this and it works, but I was wondering how I can make the code more efficient. This is what I have:
// Create a blank image with the underlying image correctly positioned
$blank = imagecreatetruecolor(403, 403);
$profile = imagecreatefromjpeg('img.jpg');
$w = imagesx($profile);
$h = imagesy($profile);
imagecopy($blank, $profile, 0, 140, 0, 0, $w, $h);
imagejpeg($blank, 'tmp.jpg', 100);
// Frame overlay
$frame = imagecreatefrompng('frame.png');
$photo = imagecreatefromjpeg('tmp.jpg');
imagecopy($photo, $frame, 0, 0, 0, 0, 403, 403);
imagejpeg($photo, 'output.jpg', 100);
// Garbage collection
unlink('tmp.jpg');
imagedestroy($blank);
imagedestroy($profile);
imagedestroy($frame);
imagedestroy($photo);
I just think that creating 2 different images is just overkill, but I just can't find a better solution.
-
\$\begingroup\$ How long does your code take to run? Would there be any benefit in finding another method? (In other words, are you trying to over-optimise?) \$\endgroup\$DaveP– DaveP2012年08月13日 13:04:46 +00:00Commented Aug 13, 2012 at 13:04
-
\$\begingroup\$ Well, the code runs pretty fast. It's just that I'd like to know if the final image could be created with only 1 imagecopy call (or with something else). I'll post this question on the codereview page you gave me Aleks, thanks. \$\endgroup\$priktop– priktop2012年08月13日 13:15:13 +00:00Commented Aug 13, 2012 at 13:15
-
\$\begingroup\$ First off, a disclaimer: I've never used any of these functions before. But it seems to me that instead of recreating the same base image every time, it might be better to create a permanent one in a "template" directory, then load it whenever you need it. Then you can make what ever changes you need and save it to the permanent directory. But this is all speculation. \$\endgroup\$mseancole– mseancole2012年08月13日 19:11:19 +00:00Commented Aug 13, 2012 at 19:11
1 Answer 1
First of all don't save your temporary file as tmp.jpg, think about what happends if there are 2 requests for an image at the same time, the first tmp.jpg will be overwritten by the second one (very unlikely, but still possible and very hard to debug / reproduce bug)..
Second saving to the disk is expensive and useless, avoid it whenever possible.
Third why do you need the blank image? I think you should have the frame image and overlay the profile image on top of it.
Given this, I think the code should look like this:
// Create a blank image with the underlying image correctly positioned
$base = imagecreatefrompng('frame.png');
$profile = imagecreatefromjpeg('img.jpg');
$w = imagesx($profile);
$h = imagesy($profile);
imagecopy($base, $profile, 0, 140, 0, 0, $w, $h);
imagejpeg($base, 'output.jpg', 100);
// Garbage collection
imagedestroy($base);
imagedestroy($profile);
Unless I miss something this code should do exactly the same thing, but faster and safer.