User tests: Successful: Unsuccessful:
Please follow the discussion below!
Currently the color to use for non-transparent images' background fill is hardcoded to black
which provides no flexibility. Allowing the users to define a desired background color fixes this.
This PR adds two new functions setFillColor
and getFillColor
as well as two new helper functions and changes the functions resize
and rotate
to use the desired fillColor, which defaults to black
preserving BC.
Example:
$files = array(
'GIF' => array(
'NO transparency in input file' => JPATH_ROOT . '/tmp/testfiles/koZs44Z.gif', // http://i.imgur.com/koZs44Z.gif
'WITH transparency in input file' => JPATH_ROOT . '/tmp/testfiles/kyxRLmz.gif' // http://i.imgur.com/kyxRLmz.gif
),
'PNG' => array(
'NO transparency in input file' => JPATH_ROOT . '/tmp/testfiles/FcoS851.png', // http://i.imgur.com/FcoS851.png
'WITH transparency in input file' => JPATH_ROOT . '/tmp/testfiles/VL9BgDi.png' // http://i.imgur.com/VL9BgDi.png
),
'JPG' => array(
'NO transparency in input file' => JPATH_ROOT . '/tmp/testfiles/TFnVnnF.jpg' // http://i.imgur.com/TFnVnnF.jpg
)
);
// Font styles for the renderer
$ftColors = array(
'none' => 'rgb(0,0,0)',
'red' => 'rgb(255,0,0)',
'green' => 'rgb(0,255,0)',
'blue' => 'rgb(0,0,255)',
'azure' => 'rgb(0,255,255)',
'pink' => 'rgb(255,0,255)',
'yellow' => 'rgb(255,255,0)',
'white' => 'rgb(255,255,255)',
'transparent' => 'rgb(0,0,0)',
// 'nonsense' => 'rgb(0,0,0)'
);
// Fill colors to pass to JImage
$bgColors = array(
'none' => array(),
'red' => array('red' => 255, 'alpha' => 33),
'green' => array( 'green' => 255, 'alpha' => 66),
'blue' => array( 'blue' => 255, 'alpha' => 99),
'azure' => array( 'green' => 255, 'blue' => 255, 'alpha' => 33),
'pink' => array('red' => 255, 'blue' => 255, 'alpha' => 66),
'yellow' => array('red' => 255, 'green' => 255, 'alpha' => 99),
'white' => array('red' => 255, 'green' => 255, 'blue' => 255),
'transparent' => array( 'alpha' => 99),
// 'nonsense' => array('red' => 'this', 'green' => 'is', 'blue' => 'all', 'alpha' => 'nonsense, but it works')
);
// Render image
$render = function($path, $extension, $title)
{
// Define neutral background color for every image to show the different fill colors don't apply when there's transparency
$neutral = 'rgb(128,128,128)';
echo '<div style="height:310px; background:' . $neutral . '; border:1px solid black; float:left;">';
echo $title;
echo '<img src="' . $path . '" alt="New Image" style="border-top:1px solid black;" />';
echo '</div>';
};
array_walk($files, function(&$inFiles, $type) use(&$render, &$bgColors, &$ftColors)
{
array_walk($inFiles, function(&$inFile, &$transparencyType) use(&$type, &$render, &$bgColors, &$ftColors)
{
echo '<h2 style="clear:both; padding-top:1em">Testing image type ' . $type . ' <small>(' . $transparencyType . ')</small></h2>';
$pathinfo = pathinfo($inFile);
$scaleFmt = JImage::SCALE_FIT;
$outPath = JPATH_ROOT . '/tmp/';
$outFile = null;
$outExt = $pathinfo['extension'];
$outType = explode('/', getimagesize($inFile)['mime']);
$outType = strtoupper( array_pop($outType) );
$outType = $outType === 'GIF' ? IMAGETYPE_GIF : ($outType === 'PNG' ? IMAGETYPE_PNG : IMAGETYPE_JPEG);
$outFmt = array('width' => '420', 'height' => '240');
$outOpts = array('quality' => 100);
$i = 1;
foreach ($bgColors as $color => &$rgb)
{
// Resize image defining no fill color (should fall back to BLACK):
$outFile = "{$outPath}{$pathinfo['filename']}-{$outFmt['width']}x{$outFmt['height']}-{$color}.{$outExt}";
$jimage = new JImage($inFile);
$jimage
->setFillColor($rgb)
->resize($outFmt['width'], $outFmt['height'], true, $scaleFmt)
->toFile($outFile, $outType, $outOpts);
$render(
str_replace(JPATH_ROOT, '', $outFile),
$outExt,
'<pre style="width:100%; text-align:center; color:' . $ftColors[$color] . '"><strong>' .
print_r("TEST {$i} ==> " . strtoupper($color) . (in_array($color, array('none','nonsense')) ? ' (falls back to BLACK)' : ''), true) .
'</strong></pre>' .
'<pre style="width:100%; text-align:center; color:' . $ftColors[$color] . '"><strong>fillColor: ' .
preg_replace('/(\}|\{)/', '', str_replace(',', ', ', str_replace('"', '', json_encode($jimage->getFillColor())))) .
'<strong></pre>'
);
$i += 1;
}
});
});
echo '<pre style="clear:both; padding-top:1em">' . print_r('Imagetest done!', true) . '</pre>';
jexit();
This will render a collection of files for every image from the footage collection.
Please report issues and code improvement suggestions!
Status | New | ⇒ | Pending |
Labels |
Added:
?
|
Category | ⇒ | Libraries |
Finally this patch works (at least this is what my test setup reflects).
Yet there's one issue which I'm wondering whether this is an issue of understanding or implementation. PNGs and GIFs are always rendered with non-image areas filled with transparency thus ignoring a defined fillColor. But, must it not be assumed that all types of images may get their non-image areas filled with the defined fillColor? If this is the case then I need some assistance as I can't seem to find the code responsible to use transparency no matter what fillColor is defined. Color processing isn't one of my favourites and I am not very experienced with all the image processing functions available.
Or am I on the wrong way and transparency goes always over a defined fillColor for PNGs and GIFs?
Hi @bembelimen, I created a screenshot showing what is rendered with the test setup described above.
There's one place on line 435 in resize()
that has an impact on the background for PNGs (currently not on GIFs).
For the sake of discussing the confusing point I disabled line 435 and added new code on lines 436-438 to render PNGs and GIFs like I understand they should be rendered with a defined fillColor. However, it doesn't apply to GIFs yet. The linked screenshot reflects what I'm talking about. If I drop lines 436 and 438 and re-enable line 435 then PNGs are rendered the way the GIFs look like - which is the initial behavior.
From my understanding of a customizable fillColor a background should always be filled with the defined fillColor no matter if its a PNG, GIF or JPEG or whatever. If I want a non-transparent fill color I should get it.
Another point is that from my point of view PNGs with transparency in the input file should render like PNGs with no transparency in the input file - filling whole transparent space with the desired fillColor. But I can't seem to find how to catch the non-transparent rectangle from the input file to copy it over into the new image filling the left area up with the desired fillColor and have it look like the PNGs with no transparency.
Get my point? Its kinda hard to explain in another language.
Hello, you are saying you are providing a link with test images , but i can not find that link. Could you please provide it. I would also agree that the transparency should be filled with the defined fillColor.
If this Issue get no Response, it will be closed at 22th September 2018.
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2018-09-23 05:15:24 |
Closed_By | ⇒ | franz-wohlkoenig |
This has been closed due to lack of response to the requests above – it can always be reopened.
Set to "closed" on behalf of @franz-wohlkoenig by The JTracker Application at issues.joomla.org/joomla-cms/10268
@itbra Hi, please provide some more testing information.
I have applied this patch in latest staging site in my local and got warnings, please see the attached screen-dump.
I have written below code in my view default.php file, let me know If I am doing anything wrong.
$jimage = new JImage('/path/to/image/file.jpg'); (I have replaced this with original image path)
// Resize image using default fill color (black):
$jimage
->resize(320, 240, true, JImage::SCALE_FIT);
// Resize image using red as fill color:
$jimage
->setFillColor(array(255)) // same as 255,0,0 - missing values are always filled from default value
->resize(320, 240, true, JImage::SCALE_FIT);
die;
This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/10268.