PHPのお勉強!

PHP TOP

imagejpeg

(PHP 4, PHP 5, PHP 7, PHP 8)

imagejpeg画像をブラウザあるいはファイルに出力する

説明

imagejpeg(GdImage $image, resource|string|null $file = null, int $quality = -1): bool

imagejpeg() は、画像 image から JPEG ファイルを作成します。

パラメータ

image

imagecreatetruecolor()のような画像作成関数が返す GdImage オブジェクト。

file

ファイル保存先のパスあるいはオープン中のリソース (この関数が値を戻した後で自動的にクローズされます)。省略したり null を設定したりした場合は、画像ストリームを直接出力します。

quality

quality はオプションであり、0(品質は最低 ですが、ファイルはより小さい)から100(品質は最高ですが、ファイルは 最大)の範囲で指定します。 デフォルト (-1) は、IJG 品質値(75) を使います。

戻り値

成功した場合に true を、失敗した場合に false を返します。

警告

しかしながら、libgd がイメージの出力に失敗した場合、この関数は true を返します。

エラー / 例外

quality が不正の場合、 ValueError をスローします。

変更履歴

バージョン 説明
8.0.0 image は、 GdImage クラスのインスタンスを期待するようになりました。 これより前のバージョンでは、有効な gd resource が期待されていました。
8.4.0 quality が不正の場合、 ValueError をスローするようになりました。

例1 JPEG 画像のブラウザへの出力

<?php
// 空の画像を作成し、テキストを追加します
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);

// content type ヘッダを、ここでは image/jpeg と設定します
header('Content-Type: image/jpeg');

// 画像を出力します
imagejpeg($im);

// メモリを開放します
imagedestroy($im);
?>

上の例の出力は、 たとえば以下のようになります。

出力例 : JPEG 画像の出力

例2 JPEG 画像のファイルへの保存

<?php
// 空の画像を作成し、テキストを追加します
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);

// 画像を 'simpletext.jpg' として保存します
imagejpeg($im, 'simpletext.jpg');

// メモリを開放します
imagedestroy($im);
?>

例3 75% 品質でのブラウザへの画像の出力

<?php
// 空の画像を作成し、テキストを追加します
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);

// content type ヘッダを、ここでは image/jpeg と設定します
header('Content-Type: image/jpeg');

// file パラメータを NULL でスキップし、品質を 75% に設定します
imagejpeg($im, NULL, 75);

// メモリを開放します
imagedestroy($im);
?>

注意

注意:

プログレッシブ JPEG を出力したい場合には、 imageinterlace() でインターレースをセットする必要があります。

参考

  • imagepng() - PNG イメージをブラウザまたはファイルに出力する
  • imagegif() - 画像をブラウザあるいはファイルに出力する
  • imagewbmp() - 画像をブラウザあるいはファイルに出力する
  • imageinterlace() - インターレースを有効もしくは無効にする
  • imagetypes() - この PHP がサポートしている画像形式を返す
add a note

User Contributed Notes 34 notes

up
44
Ray.Paseur sometimes uses Gmail
14 years ago
If string $filename is given and it exists, it will be overwritten.
up
36
francesco@essensys
15 years ago
I didn't find any example like this on the Web, so I mixed pieces together.. hope this will save time to other people!

Here's a complete solution to READ any image (gif jpg png) from the FILESYSTEM, SCALE it to a max width/height, SAVE the scaled image to a BLOB field keeping the original image type. Quite tricky..

<?php

function scaleImageFileToBlob($file) {

$source_pic = $file;
$max_width = 200;
$max_height = 200;

list(
$width, $height, $image_type) = getimagesize($file);

switch (
$image_type)
{
case
1: $src = imagecreatefromgif($file); break;
case
2: $src = imagecreatefromjpeg($file); break;
case
3: $src = imagecreatefrompng($file); break;
default: return
''; break;
}

$x_ratio = $max_width / $width;
$y_ratio = $max_height / $height;

if( (
$width <= $max_width) && ($height <= $max_height) ){
$tn_width = $width;
$tn_height = $height;
}elseif ((
$x_ratio * $height) < $max_height){
$tn_height = ceil($x_ratio * $height);
$tn_width = $max_width;
}else{
$tn_width = ceil($y_ratio * $width);
$tn_height = $max_height;
}

$tmp = imagecreatetruecolor($tn_width,$tn_height);

/* Check if this image is PNG or GIF, then set if Transparent*/
if(($image_type == 1) OR ($image_type==3))
{
imagealphablending($tmp, false);
imagesavealpha($tmp,true);
$transparent = imagecolorallocatealpha($tmp, 255, 255, 255, 127);
imagefilledrectangle($tmp, 0, 0, $tn_width, $tn_height, $transparent);
}
imagecopyresampled($tmp,$src,0,0,0,0,$tn_width, $tn_height,$width,$height);

/*
* imageXXX() only has two options, save as a file, or send to the browser.
* It does not provide you the oppurtunity to manipulate the final GIF/JPG/PNG file stream
* So I start the output buffering, use imageXXX() to output the data stream to the browser,
* get the contents of the stream, and use clean to silently discard the buffered contents.
*/
ob_start();

switch (
$image_type)
{
case
1: imagegif($tmp); break;
case
2: imagejpeg($tmp, NULL, 100); break; // best quality
case 3: imagepng($tmp, NULL, 0); break; // no compression
default: echo ''; break;
}

$final_image = ob_get_contents();

ob_end_clean();

return
$final_image;
}

?>

So, let's suppose you have a form where a user can upload an image, and you have to scale it and save it into your database.

<?php

[..] // the user has clicked the Submit button..

// Check if the user entered an image
if ($_FILES['imagefile']['name'] != '') {
$image = scaleImageFileToBlob($_FILES['imagefile']['tmp_name']);

if (
$image == '') {
echo
'Image type not supported';
} else {
$image_type = $_FILES['imagefile']['type'];
$image = addslashes($image);

$query = "UPDATE yourtable SET image_type='$image_type', image='$image' WHERE ...";
$result = mysql_query($query);
if (
$result) {
echo
'Image scaled and uploaded';
} else {
echo
'Error running the query';
}
}
}

?>
up
31
Bruno de Lima - bruno at tthedreamstone dot net
11 years ago
[[Editor's note: removed the header()-call since it is not required when outputting inline image-data]]
One single code line, solve-me after 3 hours of blind search!

here is:

... ob_start();
imagejpeg( $img, NULL, 100 );
imagedestroy( $img );
$i = ob_get_clean();

echo "<img src='data:image/jpeg;base64," . base64_encode( $i )."'>"; //saviour line!
up
5
Uplink
1 year ago
If you use the official Docker images and enable gd with `docker-php-ext-install gd`, you don't get JPEG support by default.

If that's you, and you get "Call to undefined function imagejpeg()", the you need to do this before docker-php-ext-install:

docker-php-ext-configure gd --with-jpeg

You'll also want to install libjpeg-dev for this to work.
up
7
your [dot] sheepy [at] gmail [dot] com
18 years ago
Regarding Carl Gieringer's comment, it is possible to have PHP files in utf-8. Just make sure the editor does not output BOM, which is unnecessary in utf-8 anyway.

Except for any editors from Microsoft, most programmer's editors that supports utf allows you to surpress BOM.
up
3
stefan at colulus dot com
16 years ago
I worked out a script that allows the transfer of alphanumeric data to be placed on an image. The HTML feature is img src and the php feature is imagettftext. This simple code will increment from 1 to 3 on images.

code:

<?php
//ImageCall.php -- This script will call a script to produce the image.
for($next = 1;$next < 4; $next++){
print
"Image $next:<br>";
print
"<img src = 'Image.php?\$text=$next'>";
print
"<br><br>";
}
?>

<?php
//Image.php -- This script creates a square image and places the text on it.

// image size and color
$im = ImageCreate(77,77);
$color1 = ImageColorAllocate($im,0x66,0xCC,0x00);
$color2 = ImageColorAllocate($im,0x33,0x66,0x00);
$color3 = ImageColorAllocate($im,0x00,0x99,0x00);
$color4 = ImageColorAllocate($im,0x3D,0x3D,0x3D);

// image creation
ImageFilledRectangle($im,1,1,76,76,$color1);
ImageFilledpolygon($im, array (76,1,1,76,76,76),3,$color2);
ImageFilledRectangle($im,5,5,72,72,$color3);

// determine numeric center of image
$size = ImageTTFBBox(45,0,'impact',$_GET['$text']);
$X = (77 - (abs($size[2]- $size[0])))/2;
$Y = ((77 - (abs($size[5] - $size[3])))/2 + (abs($size[5] - $size[3])));

//places numeric information on image
ImageTTFText($im,45,0,($X-1),$Y,$color4,'impact',$_GET['$text']);

//returns completed image to calling script
Header('Content-Type: image/png');
Imagejpeg($im);

?>
up
1
Bram Van Dam
19 years ago
If you wish to capture the jpg data into a variable, rather than outputting it or saving it into a file (perhaps so you can put it in a database), you might want to consider output buffering. Something along these lines should work:

<?php
ob_start
(); // start a new output buffer
imagejpeg( $newimage, NULL, 100 );
$ImageData = ob_get_contents();
ob_end_clean; // stop this output buffer
?>
up
1
viciousVelo
15 years ago
for those who get the message "permission denied" or "unable to access": it looks like a problem with your writepermissions to this folder. no matter if you use windows- or linuxserver, be sure the correct user has the permission to write to the correct folder.
up
1
Darren Kulp ( kulp at thekulp dot com )
18 years ago
With regard to chris.calo's code:

// The following block retrieves the source file. It assumes the filename extensions match the file's format.
if ( strpos($source_file,".gif") ) { $img_source = imagecreatefromgif($source_file); }
if ( (strpos($source_file,".jpg")) || (strpos($source_file,".jpeg")) )
... etc.

It assumes more than that, namely that the filename does not contain the strings '.gif', '.jpg', '.jpeg', '.bmp', or '.png' *anywhere* in the string. Some valid files with special filenames could break this; for example, a file named "used.to.be.a.png.file.gif" would cause this script to attempt to load the file as a PNG. Obviously this is a rare case, but the issue could be easily avoided by using "else ifs" (uses less CPU time) or checking that the extension abuts the end of the string or both.

That said, the whole business could be avoided if PHP didn't clutter the namespace with different functions to do the same thing with different image formats. Ick.
up
1
Elliott Brueggeman
17 years ago
I did an experiment with the image quality parameter of the imagejpeg() function when creating jpegs. I found the optimal image quality with file size is taken into account to be 80 - very close to the default value of 75.

Anything over 80 results in an unnecessary increase in file size without much increase in image quality.

Results and sample pictures: http://www.ebrueggeman.com/article_php_image_optimization.php
up
1
dklein at gmx dot de
23 years ago
Looks like any specified resolution settings in a JPEG file get lost when using imageJPEG() function in a script.
I had a high resolution JPEG which i added text to with imagestringup() so my customer can print the emailed JPEG as a filled form, but printing both Graphics from Photoshop revealed that any JPEG created is downsampled to 72 dpi, while width and height is kept.
(72 dpi is the standard web resolution)
Nothing to wonder about, but maybe if you read this you dont need to scratch your head :)
up
0
flying man
5 years ago
ZERO BYTE FILE RESULT - HERE'S WHY!

Take to heart that CAUTION note on this function. If gdlib fails to output, it still returns true! I'd call that a bug personally.

GD will fail to output if you have an image exceeding its maximum undisclosed dimensions of 65500 pixels.

You'll get a zero byte file instead
up
0
tomas at dundacek dot cz
15 years ago
I had a problem with denied permissions when trying to upload AND resize an image having safe_mode on. This caused that I couldn't create the new file in which I wanted to resampled the image with nor with imagejpeg() nor with touch() and imagejpeg() after it.

Here is my solution, I didn't test, but it's possible, it is biting some memory:

<?php
function resize($image, $target_file) {
// $image is the uploaded image
list($width, $height) = getimagesize($image['tmp_name']);

//setup the new size of the image
$ratio = $width/$height;
$new_height = 500;
$new_width = $new_height * $ratio;

//move the file in the new location
move_uploaded_file($image['tmp_name'], $target_file);

// resample the image
$new_image = imagecreatetruecolor($new_width, $new_height);
$old_image = imagecreatefromjpeg($target_file);
imagecopyresampled($new_image,$old_image,0,0,0,0,$new_width, $new_height, $width, $height);

//output
imagejpeg($new_image, $target_file, 100);
}

?>

As you can see, the function moves the uploaded file where you want to save the resampled image (move_uploaded_file is not restricted by safe_mode) and then you can resample the image, because it was created by moving it already.

Note: the directory where you want to save the file must have permissions set to 0777.
up
0
soapergem at gmail dot com
16 years ago
I came here looking for something similar to the getJPEGresolution function, but noticed the drawbacks that were pointed out in the last post. So, after drawing on some other code examples on the web, I put together the following function which should always properly return the correct values. (But remember that you still need to have the EXIF extension installed with your instance of PHP for this to work!)

<?php

function jpeg_dpi($filename)
{
if (
exif_imagetype($filename) != IMAGETYPE_JPEG ) {
return
false;
} else {
$exif = exif_read_data($filename, 'IFD0');
}

$x = $y = 0;
if ( isset(
$exif['XResolution']) && isset($exif['YResolution']) ) {
$x = intval(preg_replace('@^(\\d+)/(\\d+)$@e', '$1/$2', $exif['XResolution']));
$y = intval(preg_replace('@^(\\d+)/(\\d+)$@e', '$1/$2', $exif['YResolution']));
}

if ( !
$x && !$y && $fp = fopen($filename, 'r') ) {
$string = fread($fp, 20);
fclose($fp);

$data = bin2hex(substr($string, 14, 4));
$x = hexdec(substr($data, 0, 4));
$y = hexdec(substr($data, 4, 4));
}

if (
$x || $y ) {
return array(
$x, $y);
}

return
false;
}

?>

This function returns an array with the x-resolution, y-resolution when they can be determined, otherwise FALSE.
up
0
ahows at noggin dot com dot au
16 years ago
Regarding the code below, it only grabs the last byte of the DPI information in JFIF-mode. I was wondering why my 300-DPI file was being reported as 44. 300 - 256 = 44 of course.
up
0