3
\$\begingroup\$

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.

\$\endgroup\$
  • \$\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 Aug 13 '12 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 Aug 13 '12 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 Aug 13 '12 at 19:11
2
\$\begingroup\$

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.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.