Jump to content

Problems with image manipulation


Tanis

Recommended Posts

Hey guys, I'm having some problems with image manipulation...I have a script where you type in a hex color into a form, you hit send, and then tall of once color of in the image is changed to the color that was inputed.

<?PHP$phpHex = '525d63';$phpColor = hex2int($phpHex);$newColor = hex2int(validHexColor($_REQUEST['color'],$phpHex)) ;$im = imageCreateFromPNG('img.png');$phpCIndex = imageColorExact($im,$phpColor['r'],$phpColor['g'],$phpColor['b']);imageColorSet($im,$phpCIndex,$newColor['r'],$newColor['g'],$newColor['b']);header('Content-type: image/png');imagePNG($im);imageDestroy($im); /** * @param    $hex string        6-digit hexadecimal color * @return    array            3 elements 'r', 'g', & 'b' = int color values * @desc Converts a 6 digit hexadecimal number into an array of *       3 integer values ('r'  => red value, 'g'  => green, 'b'  => blue) */function hex2int($hex) {        return array( 'r' => hexdec(substr($hex, 0, 2)), // 1st pair of digits                      'g' => hexdec(substr($hex, 2, 2)), // 2nd pair                      'b' => hexdec(substr($hex, 4, 2))  // 3rd pair                    );}/** * @param $input string     6-digit hexadecimal string to be validated * @param $default string   default color to be returned if $input isn't valid * @return string           the validated 6-digit hexadecimal color * @desc returns $input if it is a valid hexadecimal color,  *       otherwise returns $default (which defaults to black) */function validHexColor($input = '000000', $default = '000000') {    // A valid Hexadecimal color is exactly 6 characters long    // and eigher a digit or letter from a to f    return (eregi('^[0-9a-f]{6}$', $input)) ? $input : $default ;}?>

For some reason, whenever you hit submit, you get the message "The image “http://www.mysite.com/hbt.php?color=[yourcolor]” cannot be displayed, because it contains errors." Where [yourcolor] is replaced by the color you inputed.Any ideas on whats wrong?Also, how would I make it so the user inputs two colors, and two colors on the image are changed?Finally, is there a way to have a text generator, where if the user inputs ABC, one image is generated, using the images a.png, b.png, and c.png? (I know the answer is yes, i just dont know how :) )Thanks!!

Link to comment
Share on other sites

I can't remember if function names in PHP are case-sensitive or not, but the functions are in lowercase only. If you are testing this with IE and getting the generic error page, you will either need to disable friendly HTTP errors in IE, or use another browser like Firefox or Opera, to see the actual error message.

Link to comment
Share on other sites

Hmm, I've never seen a message like "The image “http://www.mysite.com/hbt.php?color=[yourcolor]” cannot be displayed, because it contains errors." I've seen that for pages, but not for images. You may be getting another error but not seeing the message. Put this at the top of your page:

ini_set("display_errors", 1);error_reporting(E_ALL);

Link to comment
Share on other sites

You get that error if there's something wrong with the image you're loading (by going to the direct url) or if you stop the loading.But I can't see what's causing the error. What do you get if you change

header('Content-type: image/png');toheader('Content-type: text/html');

The browser should treat it as text and you should see any error messages (which can be the problem).Note : There's quite possible that you get alot "image output" (jibbrish), if you comment imagePNG($im); you can get rid of that, but on the other hand; if the erros come from imagePNG() you will loose the errors too,

Link to comment
Share on other sites

That means that the image never was outputted, why is hard to say.Are your sure that this path is correct:

$im = imageCreateFromPNG('img.png');

Is the code executed in the same dir as the image?Also try this (still with content-type: text/html, but you should perhaps move it up before this code):

if ($im = imageCreateFromPNG('img.png'))	echo 'OK';else   echo 'FALSE';

hope that can be helpful.

Link to comment
Share on other sites

  • 2 weeks later...
  • 2 weeks later...

If you aren't seeing any output, then an error is occuring. Make sure you have the error-reporting code I pasted above in your script. If you have the error-reporting code, plus the code from Mr Chisol, then you should be seeing something. Either an error message, or something from the echo statement. If you are seeing neither, then I would suspect that you don't have the code set up correctly.

Link to comment
Share on other sites

Current code-

<html><head><title>Test 2</title></head><body><?PHPini_set("display_errors", 1);error_reporting(E_ALL);$phpHex = '525d63';$phpColor = hex2int($phpHex);$newColor = hex2int(validHexColor($_REQUEST['color'],$phpHex));$im = imageCreateFromPNG('img.png');$phpCIndex = imageColorExact($im,$phpColor['r'],$phpColor['g'],$phpColor['b']);imageColorSet($im,$phpCIndex,$newColor['r'],$newColor['g'],$newColor['b']);header('Content-type: image/png');if ($im = imageCreateFromPNG('img.png'))	echo 'OK';else   echo 'FALSE';imagePNG($im);imageDestroy($im); /** * @param	$hex string		6-digit hexadecimal color * @return	array			3 elements 'r', 'g', & 'b' = int color values * @desc Converts a 6 digit hexadecimal number into an array of *	   3 integer values ('r'  => red value, 'g'  => green, 'b'  => blue) */function hex2int($hex) {		return array( 'r' => hexdec(substr($hex, 0, 2)), // 1st pair of digits					  'g' => hexdec(substr($hex, 2, 2)), // 2nd pair					  'b' => hexdec(substr($hex, 4, 2))  // 3rd pair					);}/** * @param $input string	 6-digit hexadecimal string to be validated * @param $default string   default color to be returned if $input isn't valid * @return string		   the validated 6-digit hexadecimal color * @desc returns $input if it is a valid hexadecimal color,  *	   otherwise returns $default (which defaults to black) */function validHexColor($input = '000000', $default = '000000') {	// A valid Hexadecimal color is exactly 6 characters long	// and eigher a digit or letter from a to f	return (eregi('^[0-9a-f]{6}$', $input)) ? $input : $default;}?></body></html>

Which, after sending FFFFFF and 000000 for the colors gives me "The image “http://www.habbground.com/hbt.php?color=FFFFFF&color2=000000&submit=Submit” cannot be displayed, because it contains errors."

Link to comment
Share on other sites

I think the problems you are having are because you have some HTML in that page. The browser sees "<html><head><title>Test 2</title></head><body><IMAGE DATA HERE></body></html>" with a content type of "image/png". Last I checked, PNGs can't have HTML in them.Try removing all the HTML and just keep the PHP that you have.

Link to comment
Share on other sites

This is a long shot, and it's getting late but try the following:View the source of the site in the browser (i.e. Ctrl+U in FF)Change

<?PHP

(uppercase) to

<?php

(lowercase)That's all for now, and to all a good night... :?)

Link to comment
Share on other sites

There are quite a few problems with the code above. First, as already stated, you don't want to output any HTML, or anything other then image data. You also do that here:

if ($im = imageCreateFromPNG('img.png'))   echo 'OK';else   echo 'FALSE';

You are supposed to be sending image data, "OK" and "FALSE" are not image data. Doing that type of stuff breaks the image.Aside from that, you are creating the image twice. Look at this code, with comments added:

# create a new image$im = imageCreateFromPNG('img.png');# allocate a color$phpCIndex = imageColorExact($im,$phpColor['r'],$phpColor['g'],$phpColor['b']);# set the colorimageColorSet($im,$phpCIndex,$newColor['r'],$newColor['g'],$newColor['b']);# send the image headerheader('Content-type: image/png');# create another new imageif ($im = imageCreateFromPNG('img.png'))	echo 'OK';else   echo 'FALSE';# output the imageimagePNG($im);

You create the image twice. In fact, right before you output the image you create a new one, so you're basically just outputting a new image, or really a copy of img.png. You need to read through the code and understand what you're telling it to do. I've made some changes and pasted the updated code below. I also changed the function names to be lowercase.

<?php$phpHex = '525d63';$phpColor = hex2int($phpHex);$newColor = hex2int(validHexColor($_REQUEST['color'],$phpHex));$im = imagecreatefrompng('img.png');$phpCIndex = imagecolorexact($im,$phpColor['r'],$phpColor['g'],$phpColor['b']);imageColorSet($im,$phpCIndex,$newColor['r'],$newColor['g'],$newColor['b']);header('Content-type: image/png');imagePNG($im);imageDestroy($im);/*** @param	$hex string		6-digit hexadecimal color* @return	array			3 elements 'r', 'g', & 'b' = int color values* @desc Converts a 6 digit hexadecimal number into an array of*	   3 integer values ('r'  => red value, 'g'  => green, 'b'  => blue)*/function hex2int($hex) {		return array( 'r' => hexdec(substr($hex, 0, 2)), // 1st pair of digits					  'g' => hexdec(substr($hex, 2, 2)), // 2nd pair					  'b' => hexdec(substr($hex, 4, 2))  // 3rd pair					);}/*** @param $input string	 6-digit hexadecimal string to be validated* @param $default string   default color to be returned if $input isn't valid* @return string		   the validated 6-digit hexadecimal color* @desc returns $input if it is a valid hexadecimal color, *	   otherwise returns $default (which defaults to black)*/function validHexColor($input = '000000', $default = '000000') {	// A valid Hexadecimal color is exactly 6 characters long	// and eigher a digit or letter from a to f	return (eregi('^[0-9a-f]{6}$', $input)) ? $input : $default;}?>

Link to comment
Share on other sites

First off, in that script, you are not using querystring variables called color2 or submit, so this link should work:http://www.habbground.com/hbt.php?color=FFFFFFBut it's not. This script isn't very long, so it shouldn't be having problems. Is the "img.png" in the correct location? You can add some output buffering stuff to help debug. Check the file hbt.log after the script runs to look for problems. You might also want to review imagecolorexact vs. imagecolorclosest and see which one suits your needs. The code below only replaces the top part that you have.

<?php#enable output bufferingob_start();$phpHex = '525d63';$phpColor = hex2int($phpHex);echo "phpColor:\n";print_r($phpColor);echo "\n";$newColor = hex2int(validHexColor($_REQUEST['color'],$phpHex));echo "querystring color: {$_GET['color']}\n";echo "newColor:\n";print_r($newColor);echo "\n";$im = imagecreatefrompng('img.png');$phpCIndex = imagecolorexact($im,$phpColor['r'],$phpColor['g'],$phpColor['b']);echo "Pallete color index is {$phpCIndex}\n";imagecolorset($im,$phpCIndex,$newColor['r'],$newColor['g'],$newColor['b']);echo "swapped [{$phpColor['r']},{$phpColor['g']},{$phpColor['b']}] with [{$newColor['r']},{$newColor['g']},{$newColor['b']}]\n";#get the buffer$output = ob_get_clean();#write the buffer to a log$fp = @fopen("hbt.log", "wb");@fwrite($fp, $output);@fclose($fp);header('Content-type: image/png');imagepng($im);imagedestroy($im);

Link to comment
Share on other sites

Yes, the png file is in the right spot...Strange as it may sound, it's now working, I tried it before adding in the buffer stuff, and it worked :)Anyways, how would I go about making it so the user inputs two colors, and both colors in the image are changed?Finally (rather off-topic), my other question, is there a way to have a text generator where if the user inputs ABC, one image is generated using the images a.png, b.png, and c.png? (I know the answer is yes, I just don't know how)

Link to comment
Share on other sites

You're already replacing one color, so replacing a second color is as easy as copying what you are doing now. Look up the individual functions on php.net if you don't know what they are doing.If you want to copy multiple images into a single image, you will want to use the imagecopyresampled function. You can give it a source and destination image, and you have to say which region you want to copy (x,y and width,height) and where you want to copy it to on the destination. You can also resize it while you copy, if you copy it into a region that is smaller or larger it will resize the image and resample it.Look at the reference for a description on the function and examples of how to use it.http://www.php.net/manual/en/function.imagecopyresampled.php

Link to comment
Share on other sites

You create an image large enough to fit all the images you want to combine. If the images are all 20x20, and you want to combine 4, then you need to make an image 80x20. The first image gets copied to 0,0, the second gets copied to 20,0, the third gets copied to 40,0, etc.

Link to comment
Share on other sites

Okay, but say the user inputs "Blue"How would I make it so each letter of the variable (that blue is stored in) gets added to the image, and how would i make sure the image is the right size, no matter how many letter there are?

Link to comment
Share on other sites

Well, you can add text to an image, that's not a problem. If you want to split up the letters and add an image that corresponds to each letter, I guess you can do that too. You can use the explode function to split the word into letters, and look at each letter. Or you can also access the string like an array.

for ($i = 0; $i < strlen($str); $i++){  $letter = $str[$i];}

Similarly, you will want to count how many letters there are to determine how big to make the image. That assumes that all of the letters are the same size. If the letter images are different sizes, then you need to open the image and determine how big it is yourself. If you just want to use text, there is a function to calculate how large a text string will be in a certain font and size.http://www.php.net/manual/en/function.imageftbbox.phphttp://www.php.net/manual/en/function.imagepsbbox.phphttp://www.php.net/manual/en/function.imagettfbbox.php

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...