(first posted: Jul 21, 2006)
(1722 Reads)
keywords: images phpthumb
Permalink
Working with Images in Xaraya
Articles Module
A great reference by example is the default 'picture' pubtype. Look at the user-display-picture.xd file for example.
In general, we're talking about hooking both the Uploads module, and the Images module to Articles. I don't bother with any other combination.
In this case the image uploads field contains something like this ";602" The semicolon is (i think) a legacy to distinguish this from an "older" way of representing. But if you have mutlselect images, this value will represent an array. The "602" is the file id.
Simple template code:
<xar:set name="img_output">current( xarModAPIFunc( 'uploads', 'user', 'showoutput',
array( 'value'=>$img, 'multiple'=>false) ) )</xar:set>
<xar:set name="img_file">current($img_output)</xar:set>
<xar:image-resize src="$img_file[fileId]" width="100px" height="100px"
constrain="yes" label="my image" />
Notes: showoutput returns an array. We use current() to get the first one. In the image tag, src= will give an error unless you leave out the single quotes on the array key
Xarpage Module
<xar:if condition="isset($current_page.dd.main_image)">
<xar:set name="img_output">current( xarModAPIFunc( 'uploads', 'user', 'showoutput',
array( 'value'=>$current_page['dd']['main_image'], 'multiple'=>false ) ) )</xar:set>
<div id="xb-page-image">
<img src="#$img_output['fileURL']#" />
</div>
</xar:if>
Note: I used to use
<img src="#$img_output['fileLocation']#" />
which has a value something like "var/uploads/myimage.jpg". But this doesnt work if you've uploaded a file with a duplicate file name, so the location is more like .jpg_3 , the img tag doesn't work then. So you'd better use the fileURL instead of a physical location.
However, 'fileURL' is really much slower than 'fileLocation' so if you can configure Uploads to now allow duplicates, use 'fileLocation'.
"Unable to save resized image"
If you see this on your page, its generated by the xar:image-resize tag, and could mean a number of different things:
- the data fed to image-resize is bad. For example, if the field isn't really a file uploads type, doesn't contain a valid uploads info (e.g. ";123"),
- the field is getting transformed (e.g. a body or summary field). You can turn off transforms in the pubtype config, unhook any transforming modules, and/or strip tags from the field first (such as <xar:set name="body">strip_tags($body)</xar:set>
- the derivative directory doesnt exist or not enough permissions. Make sure the Images module is configured for a valid derivatives directory. And make sure your web server has read/write/execute permission (e.g. try chmod 777 but dont necesssarily leave it that way!)
Image Tags
use <xar:image-resize> with the data from abc_output if you want to resize it
* Format : <xar:image-resize src="fileId | URL" width="[0-9]+(px|%)" [height="[0-9]+(px|%)" constrain="(yes|true|1|no|false|0)"] label="text" />
* examples:
* <xar:image-resize src="32" width="50px" height="50px" label="resize an image using pixels" />
NOTE: uses the admin api function resize_image
* <xar:image-resize src="somedir/some_image.jpg" width="25%" constrain="yes" label="resize an image using percentages" />
* <xar:image-resize src="32" setting="JPEG 800 x 600" label="process an image with predefined setting" />
* <xar:image-resize src="32" params="$params" label="process an image with phpThumb parameters" />
NOTE: this one uses phpthumb library
*
* @param $args array containing the image that you want to resize and display
* @return string the PHP code needed to invoke resize() in the BL template
Set phpthumb filters using the params arg to image-resize
zoom crop (resize so min size fills thats dimension, then crop off the extra image from other dimension)<xar:set name="thumbparam">array('w'=>100, 'h'=>100, 'zc'=>1)</xar:set> fit image so it fits within the dimensions, preserving aspect ratio, centered, using background color for margin (like watching a widescreen video on a normal set)
<xar:set name="thumbparam">array('w'=>100, 'h'=>100, 'far'=>1)</xar:set> baraboom: <xar:set name="param">array('zc' => 1, 'w' => 180, 'h' => 180, 'fltr' => array('/home/httpd/vhosts/path/htm//themes/gfx/activity_blog_thumb.png'))</xar:set>
See images/xardocs/phpthumb.readme.txt for options.
Sample Dump of Img_Output
Array( [fileId] => 602 [userId] => 3 [userName] => Administrator [fileName] => 100_3671.JPG [fileLocation] => var/uploads/100_3671.JPG_1 [fileSize] => 554365 [fileStatus] => 2 [fileType] => image/jpeg [fileTypeInfo] => Array( [typeId] => 5 [subtypeId] => 155 ) [storeType] => 3 [mimeImage] => modules/mime/xarimages/image-jpeg.png [fileDownload] => http://localhost/alumbiz/?module=uploads&func=download&fileId=602 [fileURL] => http://localhost/alumbiz/?module=uploads&func=download&fileId=602 [DownloadLabel] => Download file: 100_3671.JPG [fileModified] => 1164862446 [fileDirectory] => imports [fileHash] => 100_3671.JPG_1 [fileHashName] => imports/100_3671.JPG_1 [fileHashRealName] => imports/100_3671.JPG [fileStatusName] => Approved )
Here's another nice snippet of template code
<xar:if condition="xarModIsHooked('uploads','articles',$pubtypeid) and substr($body,0,1) eq ';'">
<xar:set name="img_output">xarModAPIFunc('uploads','user','showoutput',array('value' => $body, 'multiple' => true))</xar:set>
<xar:foreach in="$img_output" key="$fileId" value="$fileInfo">
<a href="http://www.vaporbase.com/index.php#$fileInfo['fileDownload']#" title="#xarMl('View full sized image')#">
<xar:if condition="xarModIsAvailable('images')">
<xar:set name="file">$fileInfo</xar:set>
<!-- <xar:image-resize src="$file[fileId]" label="$title" width="400px" constrain="true"/> -->
<xar:image-resize src="$file[fileId]" label="$title" setting="jpg400x400"/>
<xar:else />
<img src="#xarModURL('uploads', 'user', 'download', array('fileId' => $fileInfo['fileId']))#" width="100%" alt="#$title#" id="thephoto" />
</xar:if>
</a>
<br />
<span class="xar-sub">Click to download full sized image</span>
<xar:set name="size">xarModAPIFunc('misctools','user','human_file_size', array('size'=>$fileInfo['fileSize']))</xar:set>
<xar:set name="finfo">xarModAPIFunc('images','user','getimageinfo',array('fileId'=>$fileInfo['fileId']))</xar:set>
<table>
<tr><td align="right">File name: </td><td>#$fileInfo['fileName']#</td></tr>
<tr><td align="right">File size: </td><td>#$size#</td></tr>
<xar:if condition="!empty($finfo['imageWidth'])">
<tr><td align="right">Width x Height:</td><td>#$finfo['imageWidth']# x #$finfo['imageHeight']# pixels</td></tr>
</xar:if>
</table>
</xar:foreach>
<xar:else />
<img src="#$body#" border="0" alt="#$title#" id="thephoto" />
</xar:if>
Replacing the uploaded image with a resized one
This tag displays the original uploaded image:
<img src="#$img_output['fileURL']#" />
This tag displays the resized image from the derivative directory:
<xar:image-resize src="$img_output[fileId]" width="100px" height="100px" constrain="yes" label="my image" />
I'm not sure what happens if you delete the original (e.g via admin interface or commandline) , whether this tag will still work.
But if you really want to replace the uploaded image with the resized one, you can use the replace_image api:
<xar:set name="loc">xarModApiFunc('images','admin','replace_image', array('fileId'=>$img_output['fileId'], 'width'=>'100px', 'height'=>'100px', 'constrain'=>'1'))</xar:set> Unfortunately the constrain does not seem to work when both width and height are specified.
This uses some "old" api, which calls gd (or your other image libraries) directly, it does not call phpThumb.
Analysis of the code:
replace_image calls resize_image, which calls load_image, which returns an object of class Image_Properties, extended by Image_GD class. Resize calls $image->resize() which is defined in the GD class, thus GD library is called directly, not phpThumb.
Use the process_image api function instead...
process_image function
Ah, the master of the universe! well, the phpThumb universe anyway.
$newLocationString = xarModApiFunc('images','admin','process_image', $params ); * @param array $image The image info array (e.g. coming from getimageinfo or getimages/getuploads/getderivatives)
* @param integer $saveas How to save the processed image (0 = derivative, 1 = [image]_new.[ext], 2 = replace, 3 = output)
* @param string $setting The predefined setting to use, or
* @param array $params The phpThumb parameters to use
* @param boolean $iscached Check if the processed file already exists (default FALSE)
* @return string the location of the newly processed image
Not Working?
I had a problem that image resize wasn't working, just crashed. Actually the version of the tag that calls gd directly worked, the version that uses phpthumb crashed (see above). In the end I just needed to bump up my php memory limits (from 32m to 64m).
There's some suggestions here: http://us3.php.net/imagecreatefromjpeg for dynamically increasing the memory limit based on the image size. Here's my function (installed in my custom "MiscTools" module, xaruserapi/setmemoryforimage.php):
<?php
/**
* increases php memory limit for processing an jpg image
* @param $args['file'] file name of image file
*/
function misctools_userapi_setmemoryforimage($args) {
extract($args);
return setMemoryForImage( $file );
}
/* ================= */
function setMemoryForImage( $filename )
{
$imageInfo = getimagesize($filename);
$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 );
$memoryLimitMB = (integer) ini_get('memory_limit'); // assumes compiled with "--enable-memory-limit"
$memoryLimit = $memoryLimitMB * $MB;
if ( function_exists('memory_get_usage') &&
memory_get_usage() + $memoryNeeded > $memoryLimit)
{
$newLimit = $memoryLimitMB + ceil( ( memory_get_usage()
+ $memoryNeeded - $memoryLimit ) / $MB);
$newLimit += 3; // additional fudge factor
ini_set( 'memory_limit', $newLimit . 'M' );
} else {
return false;
}
}
?>
UPDATE: I had a different case of using <xar:image-resize> on a reasonably sized jpg file crashing. It turns out it dies on the file open call in GD library, before the image is processed. I submitted a bug report with changes to file modules/images/xarclass/image_gd.php using this set_memory algorithm, but I'm not sure its general enough to be a patch http://bugs.xaraya.com/show_bug.cgi?id=6091
Privileges
Another thing, if you require uploads be approved (default state "submitted") the files may not be accessible until approved. This one got me because things were working fine, then seemed to stop. Turns out I was testing while logged in as Admin, then when testing as anon the uploaded pix weren't showing up (Uploads showout function returns null).
OH, AND...
If you use short URL's on the Images module, and have an images/ directory in your web root, that could cause problems. (Or not, depending on how your web server is setup). Just one more thing to think about.
There are no comments attached to this item.



