Beta 42

Research and Development

Menu

Resizable Cell Background Image with PHP

Putting dynamic content inside a table cell can be challenging sometimes, especially if the content is a picture of unknown size and it is required by design to put a custom cell background to fit the picture, like a frame (as displayed on Picture 1 and Picture 2). All parameters (picture size, cell size and background image size) need to be determined and calculated on the fly.

Cell with frame:

Cell with picture inside the frame:

If you are targeting browsers that support CSS3 specification, you can simply use [background-size](http://www.w3.org/TR/2002/WD-css3-background-20020802/#background-size) property. If not, some basic tricks may be applied.

Creating the table

Listing 1 - index.php:

<html>
<head>
    <title>Resizable Cell Background</title>
</head>
<body>

<?php
$pic_path = "picture.jpg";
?>

<table border="0" cellpadding="0" cellspacing="0" align="center">
    <tr>
        <td align="center" valign="middle">

            <img src="<?php echo $pic_path; ?>" />

        </td>
    </tr>
</table>
</body>
</html>

Apart from taking the picture path in front of the table code, the whole page on Listing 1 is a simple html single cell table on top of the page, centered horizontally.

Variable $pic_path is singled out on top for two reasons. First, only in this simple example it is statically assigned. In real life example, it will be a result of some search, or assigned as a next picture path of some picture album slideshow. Second, it will be used for other parameters calculation.

Setting the parameters

First we need to determine the picture size and set the cell size a bit bigger (for the frame). For the images approximately 800 x 600 pixels, a good offset might be 20 pixels. Cell width and height will be adjusted accordingly on the fly.

Listing 2 - index.php:

<html>
<head>
    <title>Resizable Cell Background</title>
</head>
<body>

<?php
$pic_path = "picture.jpg";
$frame_offset = 20;
list($pic_wid, $pic_hei) = getimagesize($pic_path);
$cel_wid = $pic_wid + 2 * $frame_offset;
$cel_hei = $pic_hei + 2 * $frame_offset; 
?>

<table border="0" cellpadding="0" cellspacing="0" align="center">
    <tr>
        <td align="center" valign="middle" width="<?php echo $cel_wid; ?>" 
            height="<?php echo $cel_hei; ?>">

            <img src="<?php echo $pic_path; ?>" />

        </td>
    </tr>
</table>
</body>
</html>

Alternatively, you can set the offset to 2.5% of the picture width: $frame_offset = (int)($pic_wid * 0.025); and be sure that parameter would be good for any picture size.

Stretching the background image

At this stage, we have a picture comfortably centered inside a table cell, with an offset of 20 pixels all around it. Also, we have the dimensions for the frame ($cel_wid and $cel_hei) to fit into the cell as a background image.

For the frame we will need a predefined image, created in Photoshop, or downloaded from the Internet. The dimensions of the predefined frame depend of the pictures we need to display. We do not want to stretch the frame too much because it might not look nice after scaling. On the other hand, if the frame image is too big it will take longer to load, process and display (after all, it is only a background image). A bit of testing in the real case scenario might help you to decide what image size to use.

As mentioned above, we cannot set the background image size. That is where PHP comes handy. We will use a PHP generated image, based on the size parameters and the predefined frame image, shown on Listing 3.

Listing 3 - frame.php:

<?php

$frameWid = $_REQUEST['frame_wid'];
$frameHei = $_REQUEST['frame_hei'];

$frame_path = "frame.jpg";

$frame = imagecreatefromjpeg($frame_path);
list($frame_wid, $frame_hei) = getimagesize($frame_path);
$image = imagecreatetruecolor($frameWid, $frameHei);
imagecopyresampled($image, $frame, 0, 0, 0, 0, $frameWid, $frameHei, $frame_wid, $frame_hei);

header('Content-type: image/jpeg');
imagejpeg($image);
imagedestroy($image);

?>

We can use the PHP dynamically created image the same way as we would use the normal picture, except for passing the parameters to it (if required, as in this case). For example, we can use it as: frame.php?frame_wid=800&frame_hei=600. The complete code is on Listing 4.

Listing 4 - index.php:

<html>
<head>
    <title>Resizable Cell Background</title>
</head>
<body>

<?php

$pic_path = "picture.jpg";
list($pic_wid, $pic_hei) = getimagesize($pic_path);

$frame_offset = 20;

$cel_wid = $pic_wid + 2 * $frame_offset;
$cel_hei = $pic_hei + 2 * $frame_offset;

?>

<table border="0" cellpadding="0" cellspacing="0" align="center">
    <tr>
        <td align="center" valign="middle" width="<?php echo $cel_wid; ?>" 
            height="<?php echo $cel_hei; ?>" style="background-image: 
            url(frame.php?frame_wid=<?php echo $cel_wid; ?>&frame_hei=<?php echo $cel_hei; ?>);">

            <img src="<?php echo $pic_path; ?>" />

        </td>
    </tr>
</table>
</body>
</html>

Future development

As an improvement of the example above, it is possible to add a code to check if the picture size is within the set boundaries and scale it if necessary. Let's say that the picture should not be larger than 800 pixels in width and 600 pixels in height, as displayed on Listing 5.

Listing 5 - index.php:

<html>
<head>
    <title>Resizable Cell Background</title>
</head>
<body>

<?php

$pic_path = "picture.jpg";
list($pic_wid, $pic_hei) = getimagesize($pic_path);
$pic_max_wid = 800;
$pic_max_hei = 600;

if($pic_wid > $pic_max_wid)
{
    $pic_hei = (int)($pic_hei * $pic_max_wid / $pic_wid);
    $pic_wid = $pic_max_wid;
}
if($pic_hei > $pic_max_hei)
{
    $pic_wid = (int)($pic_wid * $pic_max_hei / $pic_hei);
    $pic_hei = $pic_max_hei;
} 
$frame_offset = 20;

$cel_wid = $pic_wid + 2 * $frame_offset;
$cel_hei = $pic_hei + 2 * $frame_offset;

?>

<table border="0" cellpadding="0" cellspacing="0" align="center">
    <tr>
        <td align="center" valign="middle" width="<?php echo $cel_wid; ?>" 
            height="<?php echo $cel_hei; ?>" style="background-image: 
            url(frame.php?frame_wid=<?php echo $cel_wid; ?>&frame_hei=<?php echo $cel_hei; ?>);">

            <img src="<?php echo $pic_path; ?>" height="<?php echo $pic_hei; ?>" 
            width="<?php echo $pic_wid; ?>" />

        </td>
    </tr>
</table>
</body>
</html>