Wednesday, October 22, 2008

PHP: imagecopyresampled results in part black images

When using imagecopyresampled parts of the destination images was black. I solved this by using a script found on PHP.net that increases the memory limit for PHP, since large source images requires large amount of memory.

I did some modifications though, since I wanted the script to work for jpeg, gif and png, and I also returned the original memory limit for the script so that it would be easy to restore the memory limits after the image processing.

Anyway, here's the script:

/**
* Increases the memory limit for PHP so that images can be loaded
*
* @param string $filename - full path to the image file to be used
* @return int - old memory limit so that you can restore the memory limit after image processing
*/
function _memorySize($filename){
$imageInfo = getimagesize($filename);

if(strpos($filename,'.jpg')===false){
$imageInfo['bits']=24;
$imageInfo['channels']=16;
}
$MB = Pow(1024,2); // number of bytes in 1M
$K64 = Pow(2,16); // number of bytes in 64K
$TWEAKFACTOR = 1.8; // Or whatever works for you
$memoryNeeded = round( ( $imageInfo[0] * $imageInfo[1]
* $imageInfo['bits']
* $imageInfo['channels'] / 8
+ $K64
) * $TWEAKFACTOR
);
$memoryHave = memory_get_usage();
$memoryLimitMB = (integer) ini_get('memory_limit');
$memoryLimit = $memoryLimitMB * $MB;
if ( function_exists('memory_get_usage')
&& (($memoryHave + $memoryNeeded) < $memoryLimit)
) {
$newLimit = $memoryLimitMB + ceil( ( $memoryHave
+ $memoryNeeded
- $memoryLimit
) / $MB
);
ini_set( 'memory_limit', $newLimit . 'M' );
return $memoryLimitMB;
}
return false;
}

Setting margin, padding and designMode enable a javascript created iframe in Firefox

It was a little bit tricky to designMode enable and change the style of a javascript created iframe in firefox.

Anyway, the trick seems to be to wait a little with a setTimeout before setting designMode='on' and changing the style of the javascript created iframe.

My successfull code looks like this [Firefox only, not IE]:


function addEditableField(parent, iframeId){
// Create the iframe, give it an id and attach it to an existing dom-element
var newIFrame = document.createElement('iframe');
newIFrame.id = 'iframeId';
document.getElementById(parent).appendChild(newIFrame);
// Wait a little for the iframe document to be prepared before doing stuff to it
setTimeout("enable('"+iframeId+"')",20);
}

function enable(id){
// Now some time has passed, so now we can play with the iframe:
document.getElementById(id).contentWindow.document.designMode='on';
document.getElementById(id).contentWindow.document.body.style.margin = '3px';
document.getElementById(id).contentWindow.document.body.style.padding = '3px';
}

addEditableField('parentDiv','testField');


And that's it. (Btw, sorry for the long title, but I prefer to know what I'll get when I go somewhere using google).