1

I have installed GD on my PHP Version 5.6.32 server.

GD Support  enabled
GD headers Version  2.2.4
GD library Version  2.2.4
FreeType Support    enabled
FreeType Linkage    with freetype
FreeType Version    2.8.0
GIF Read Support    enabled
GIF Create Support  enabled
JPEG Support    enabled
libJPEG Version unknown
PNG Support enabled
libPNG Version  1.6.29
WBMP Support    enabled
XPM Support enabled
libXpm Version  30411
XBM Support enabled

Here is the function creating the image:

  // Print a bar image
  static function printBarImage($color, $width, $height) {
    // Create a blank image
    $image = imagecreatetruecolor($width, $height);

    if (strlen($color) == 6) {
      $color = "#" . $color;
    }

    $r = intval(substr($color, 1, 2), 16);
    $g = intval(substr($color, 3, 2), 16);
    $b = intval(substr($color, 5, 2), 16);
    $color = imagecolorallocate($image, $r, $g, $b);

    // Fill up the image background
    imagefilledrectangle($image, 0, 0, $width, $height, $color);

    // Header indicating the image type
    header("Content-type:image/jpeg"); // <<== This is the line 467

    // Create the image in the best jpeg quality
    imagejpeg($image, NULL, 100);

    // Destroy the image
    imagedestroy($image);
  }

This above function is called by the script:

<?PHP

require_once("website.php");

ob_end_flush(); // <<== Added for debugging purposes

$color = LibEnv::getEnvHttpGET("color");
$width = LibEnv::getEnvHttpGET("width");
$height = LibEnv::getEnvHttpGET("height");

$color = urldecode($color);

if ($color && $width > 0 && $height> 0) {
  LibImage::printBarImage($color, $width, $height);
}

?>

But it won't display any image.

You can see it in action at http://www.thalasoft.com/engine/system/utils/printBarImage.php?color=%2392299FF&width=30&height=100

My phpinfo page shows the default_charset to be UTF-8.

But the file is in the charset:

$ uchardet system/utils/printBarImage.php 
ascii/unknown

The file contains no BOM character:

$ head -c 3 system/utils/printBarImage.php | hexdump -C
00000000  3c 3f 50                                          |<?P|
00000003

The same issue occurs with the functions imagepng or imagejpeg.

I know the image is created for if I call the function as imagepng($image, "/usr/bin/learnintouch/engine/image.jpeg"); then it creates the /usr/bin/learnintouch/engine/image.jpeg file on the file system and I can open it in another browser tab and see the image.

Even saving the image, it cannot be read later on, no image is displayed:

//imagejpeg($image, "/usr/bin/learnintouch/engine/image.jpeg", 100);
readfile("/usr/bin/learnintouch/engine/image.jpeg");

Following Phil's advice, I added an ob_end_flush(); call, which gives the following error (the line number is marked above in the source code as well) in my dev environment:

Error message: Cannot modify header information - headers already sent by (output started at /usr/bin/learnintouch/engine/system/utils/printBarImage.php:5)
Filename: /usr/bin/learnintouch/engine/lib/image.php
Line: 467

On the public test environment at http://www.thalasoft.com/engine/system/utils/printBarImage.php?color=%2392299FF&width=30&height=100 it displays garbled characters.

UPDATE: Commenting on the solution... I added the ob_end_clean(); function call to the script file, and the image then was displayed all right. The script file now reads:

<?PHP

require_once("website.php");

// Prevent any possible previous header from being sent before the following image header that must be the first
ob_end_clean();

$color = LibEnv::getEnvHttpGET("color");
$width = LibEnv::getEnvHttpGET("width");
$height = LibEnv::getEnvHttpGET("height");

$color = urldecode($color);

if ($color && $width > 0 && $height> 0) {
  LibImage::printBarImage($color, $width, $height);
}

?>
Stephane
  • 11,836
  • 25
  • 112
  • 175
  • 1
    You appear to have some invalid characters at the start of your output ~ *"Not a JPEG file: starts with 0x0a 0xff"*. Appears to be a newline. What does your PHP script look like that calls your `printBarImage` function? – Phil Nov 21 '17 at 00:54
  • Remember, the image can be displayed fine when saved and opened in another browser tab. – Stephane Nov 21 '17 at 00:57
  • 1
    Right, so the unwanted characters are coming from somewhere outside your `printBarImage` function – Phil Nov 21 '17 at 00:59
  • If I download a jpeg image from a page somewhere on the web, and try to display it in this function, it won't. I suspect the charset of my PHP server being different than the one of my PHP source code files... – Stephane Nov 21 '17 at 01:01
  • 1
    I'd say that's unlikely. What is probable is you have some whitespace displaying somewhere before a ``. I strongly suggest you [omit the closing PHP tag](https://stackoverflow.com/questions/3219383/why-do-some-scripts-omit-the-closing-php-tag) in all your scripts – Phil Nov 21 '17 at 01:38
  • Does your `printBarImage.php` script `include` or `require` any other scripts? – Phil Nov 21 '17 at 01:40
  • Yes it includes the main bundle of scripts. – Stephane Nov 21 '17 at 09:21

2 Answers2

1

Taking some liberties here but this is what I picture is happening.

Given your printBarImage function is static, I'm guessing it's part of a class. I would also guess that the class is in its own file and it looks something like this

<?php
// ImageUtils.php
class ImageUtils {
    static function printBarImage($color, $width, $height) {
        // ...
    }
}
?>

I imagine your printBarImage.php PHP file looks something like

<?php
require_once 'ImageUtils.php';
ImageUtils::printBarImage($_GET['color'], $_GET['width'], $_GET['height']);

The issue is most likely that your class .php file has some trailing whitespace.

Specifically (with whitespace annotations)

?>$
$

Thus, your printBarImage.php script outputs a newline character right at the top, before the binary image data.

The solution is to omit the final closing PHP tag at the end of all your .php files.


I'm also guessing your PHP environment has output buffering enabled. I don't recommend this. Were you to disable it, you would probably see something like

Warning: Cannot modify header information - headers already sent by (output started at ImageUtils.php:<last line>) in ImageUtils.php on line <line with header(...)>

Even if I'm wrong about the location of the whitespace character, you should still try disabling output buffering to help pinpoint the problem.

Phil
  • 157,677
  • 23
  • 242
  • 245
  • I looked in the code base, and could not see any `ob_...` functions being used in there. – Stephane Nov 21 '17 at 09:28
  • Note that the same code base works fine deployed on another server. Of course, that does not exclude a white space added somewhere by mistake in this environment. – Stephane Nov 21 '17 at 09:31
0

after downloading your "image" stream, it looks like there is an extra data at the front of your "image" stream.

it looks that your script is sending something before the image.

my suspicion lies in three places:

1. you might have extra whitespace in front of your <?php

<?php ?> clean any unnecessary whitespace

2. your include("website.php"); might have output something

check your included files for outputs

3. ob_end_flush() is emitting whatever it has in the buffer

you should use ob_end_clean() if you want to discard any buffer

am05mhz
  • 2,727
  • 2
  • 23
  • 37
  • Using the `ob_end_clean()` function allowed the image to be displayed. Indeed there must be some output sneaking out somewhere in the included bundle. – Stephane Nov 21 '17 at 11:52