Ask your WordPress questions! Pay money and get answers fast! (more info)

wp_get_attachment() resize mod needed

  • SOLVED

[[LINK href="http://shawn.theanointedone.com/photogallery/tiltshift-gallery-7/"]]http://shawn.theanointedone.com/photogallery/tiltshift-gallery-7/[[/LINK]]

I need a function to make my gallery more streamlined

I am pulling in all the image attachments that belong to the post in question. The problem is that it pulls in the full size image which causes all kinds of problems.

--I want to resize the image that is going to be displayed in the thumbnails and the slider properly. (the thumbs and large image are resized via css, which is not good for page load times).

Here is the relevent sourcecode of the single.php page itself, so you can see what I am doing:

<div id="content-slideshowgallery" class="col-full">

<div id="main-sidebar-container">




<?php if (have_posts()) : $count = 0; ?>
<?php while (have_posts()) : the_post(); $count++; ?>

<div id="gallery" class="content">

<div id="controls" class="controls"></div>

<div class="slideshow-container">

<div id="loading" class="loader"></div>
<div id="slideshow" class="slideshow"></div>

</div>

</div>

<div id="thumbs" class="navigation">

<ul class="thumbs noscript">

<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {

echo '<li>';
echo '<a class="thumb" href= ' . wp_get_attachment_url( $attachment_id, $size = 'large' ) . ' width="600px" title=' . apply_filters( 'the_title', $attachment->post_title ) . '>';
echo '<img src= ' . wp_get_attachment_thumb_url( $attachment_id ) . ' width="50px" alt=' . apply_filters( 'the_title', $attachment->post_title ) . ' ></a>';
echo '<div class="caption">';
echo 'title=' . apply_filters( 'the_title', $attachment->post_title ) . '';
echo '</div>';
echo '</a>';
echo '</li>';
} ?>

</ul>

</div><!-- thumbs.navigation -->


<?php endwhile; else: ?>
<div class="post">
<p><?php _e('Sorry, no posts matched your criteria.', 'woothemes') ?></p>
</div><!-- /.post -->
<?php endif; ?>


<div id="caption" class="caption-container"></div>


</div><!-- /#main-sidebar-container -->

</div><!-- /#content -->



What I envision:

Start by grabbing the attachment images, then run it through a resizer, to make it so the max width of the large image is 800px, and the max height is 550px.

Do the same for the thumbnail images so they are max width 100px, max height 50px.

This way I don't have to worry about a user uploading huge images from a digital camera, and having my gallery trying to load a bunch of gigantic images.

**those familiar with woo themes
we have the function woo_image() that takes a src paramater, and also allows height=x&width=x which may work for this...

Answers (2)

2010-11-05

Victor Teixeira answers:

I have the perfect script for you.
This is a function I made some days ago to resize images on the fly using wp native functions.


/*
* Resize images dynamically using wp built in functions
* Victor Teixeira
*
* php 5.2+
*
* Exemple use:
*
* <?php
* $thumb = get_post_thumbnail_id();
* $image = vt_resize( $thumb,'' , 140, 110, true );
* ?>
* <img src="<?php echo $image[url]; ?>" width="<?php echo $image[width]; ?>" height="<?php echo $image[height]; ?>" />
*
* @param int $attach_id
* @param string $img_url
* @param int $width
* @param int $height
* @param bool $crop
* @return array
*/
function vt_resize( $attach_id = null, $img_url = null, $width, $height, $crop = false ) {

// this is an attachment, so we have the ID
if ( $attach_id ) {

$image_src = wp_get_attachment_image_src( $attach_id, 'full' );
$file_path = get_attached_file( $attach_id );

// this is not an attachment, let's use the image url
} else if ( $img_url ) {

$file_path = parse_url( $img_url );
$file_path = ltrim( $file_path['path'], '/' );
//$file_path = rtrim( ABSPATH, '/' ).$file_path['path'];

$orig_size = getimagesize( $file_path );

$image_src[0] = $img_url;
$image_src[1] = $orig_size[0];
$image_src[2] = $orig_size[1];
}

$file_info = pathinfo( $file_path );
$extension = '.'. $file_info['extension'];

// the image path without the extension
$no_ext_path = $file_info['dirname'].'/'.$file_info['filename'];

$cropped_img_path = $no_ext_path.'-'.$width.'x'.$height.$extension;

// checking if the file size is larger than the target size
// if it is smaller or the same size, stop right here and return
if ( $image_src[1] > $width || $image_src[2] > $height ) {

// the file is larger, check if the resized version already exists (for crop = true but will also work for crop = false if the sizes match)
if ( file_exists( $cropped_img_path ) ) {

$cropped_img_url = str_replace( basename( $image_src[0] ), basename( $cropped_img_path ), $image_src[0] );

$vt_image = array (
'url' => $cropped_img_url,
'width' => $width,
'height' => $height
);

return $vt_image;
}

// crop = false
if ( $crop == false ) {

// calculate the size proportionaly
$proportional_size = wp_constrain_dimensions( $image_src[1], $image_src[2], $width, $height );
$resized_img_path = $no_ext_path.'-'.$proportional_size[0].'x'.$proportional_size[1].$extension;

// checking if the file already exists
if ( file_exists( $resized_img_path ) ) {

$resized_img_url = str_replace( basename( $image_src[0] ), basename( $resized_img_path ), $image_src[0] );

$vt_image = array (
'url' => $resized_img_url,
'width' => $new_img_size[0],
'height' => $new_img_size[1]
);

return $vt_image;
}
}

// no cached files - let's finally resize it
$new_img_path = image_resize( $file_path, $width, $height, $crop );
$new_img_size = getimagesize( $new_img_path );
$new_img = str_replace( basename( $image_src[0] ), basename( $new_img_path ), $image_src[0] );

// resized output
$vt_image = array (
'url' => $new_img,
'width' => $new_img_size[0],
'height' => $new_img_size[1]
);

return $vt_image;
}

// default output - without resizing
$vt_image = array (
'url' => $image_src[0],
'width' => $image_src[1],
'height' => $image_src[2]
);

return $vt_image;
}



Just put the function on your functions.php file and then on your template sustitute the foreach loop with this:


<?php
foreach ( $attachments as $attachment ) :
$imagem = vt_resize( $attachment->ID,'' , 110, 90 );
?>
<li>
<a href="<?php echo $attachment->post_content; ?>" class="thumb" title="<?php echo $attachment->post_title; ?>"><img src="<?php echo $imagem[url]; ?>" width="<?php echo $imagem[width]; ?>" height="<?php echo $imagem[height]; ?>" />
<div class="caption"><?php echo $attachment->post_title; ?></div>
</a>
</li>
<?php endforeach; ?>



It will resize and cache your images for future requests.

Have a nice day.

PS: I just sent this function to wp trac: http://core.trac.wordpress.org/ticket/15311


Victor Teixeira comments:

Of course this line
$imagem = vt_resize( $attachment->ID,'' , 110, 90 );

Should be
$imagem = vt_resize( $attachment->ID,'' , 800, 550 );

For the size you want.


Victor Teixeira comments:

Just made another fix. The full code on the template should be:


<?php
foreach ( $attachments as $attachment ) :
$image = vt_resize( $attachment->ID,'' , 800, 550 );
$thumb = vt_resize( $attachment->ID,'' , 150, 120 );
?>
<li>
<a href="<?php echo $image[url]; ?>" class="thumb" title="<?php echo $attachment->post_title; ?>"><img src="<?php echo $thumb[url]; ?>" width="<?php echo $thumb[width]; ?>" height="<?php echo $thumb[height]; ?>" />
<div class="caption"><?php echo $attachment->post_title; ?></div>
</a>
</li>
<?php endforeach; ?>



Of course you can edit the sizes on the $image and $thumb variables.


shawn comments:

This function is working perfectly!

One last question before I select it as the winner...

my thumbnails are resizing proportionally as I'm guessing they should.. however, I would like to force them into a width/height if possible with this function so they look uniform on the bottom.

is this possible?

http://shawn.theanointedone.com/photogallery/tiltshift-gallery-7/


very very nice script!


shawn comments:

sorry one final question...

Is it possible to have a 'quality control' during the resize so that I can force the resized image to have a lower quality like photoshop does?

my woo_image() function does that where I say woo_image(q='50'&width=x...)

As I can see users uploading a lot of pics to a gallery page, just doing whatever I can to manage the load time for end users


Victor Teixeira comments:

If you want to crop the images for them to fit an specific size just add ,true after the image sizes:


thumb = vt_resize( $attachment->ID,'' , 150, 120, true );


shawn comments:

Thank you, your an obvious winner with this one.

I read the code, no quality control built in, maybe a good idea for later?

either way, it works, thank you very much...


Victor Teixeira comments:

New function with jpeg quality support:


/*
* Redimensiona imagens dinamicamente utilizando funções nativas do wp
* Victor Teixeira
*
* php 5.2+
*
* Exemplo de uso:
*
* <?php
* $thumb = get_post_thumbnail_id();
* $image = vt_resize( $thumb,'' , 140, 110, true, 80 );
* ?>
* <img src="<?php echo $image[url]; ?>" width="<?php echo $image[width]; ?>" height="<?php echo $image[height]; ?>" />
*
* @param int $attach_id
* @param string $img_url
* @param int $width
* @param int $height
* @param bool $crop
* @return array
*/
function vt_resize( $attach_id = null, $img_url = null, $width, $height, $crop = false, $jpeg_quality = 90 ) {

// this is an attachment, so we have the ID
if ( $attach_id ) {

$image_src = wp_get_attachment_image_src( $attach_id, 'full' );
$file_path = get_attached_file( $attach_id );

// this is not an attachment, let's use the image url
} else if ( $img_url ) {

$file_path = parse_url( $img_url );
$file_path = ltrim( $file_path['path'], '/' );
//$file_path = rtrim( ABSPATH, '/' ).$file_path['path'];

$orig_size = getimagesize( $file_path );

$image_src[0] = $img_url;
$image_src[1] = $orig_size[0];
$image_src[2] = $orig_size[1];
}

$file_info = pathinfo( $file_path );
$extension = '.'. $file_info['extension'];

// the image path without the extension
$no_ext_path = $file_info['dirname'].'/'.$file_info['filename'];

$cropped_img_path = $no_ext_path.'-'.$width.'x'.$height.$extension;

// checking if the file size is larger than the target size
// if it is smaller or the same size, stop right here and return
if ( $image_src[1] > $width || $image_src[2] > $height ) {

// the file is larger, check if the resized version already exists (for $crop = true but will also work for $crop = false if the sizes match)
if ( file_exists( $cropped_img_path ) ) {

$cropped_img_url = str_replace( basename( $image_src[0] ), basename( $cropped_img_path ), $image_src[0] );

$vt_image = array (
'url' => $cropped_img_url,
'width' => $width,
'height' => $height
);

return $vt_image;
}

// $crop = false
if ( $crop == false ) {

// calculate the size proportionaly
$proportional_size = wp_constrain_dimensions( $image_src[1], $image_src[2], $width, $height );
$resized_img_path = $no_ext_path.'-'.$proportional_size[0].'x'.$proportional_size[1].$extension;

// checking if the file already exists
if ( file_exists( $resized_img_path ) ) {

$resized_img_url = str_replace( basename( $image_src[0] ), basename( $resized_img_path ), $image_src[0] );

$vt_image = array (
'url' => $resized_img_url,
'width' => $new_img_size[0],
'height' => $new_img_size[1]
);

return $vt_image;
}
}

// no cache files - let's finally resize it
$new_img_path = image_resize( $file_path, $width, $height, $crop, $jpeg_quality );
$new_img_size = getimagesize( $new_img_path );
$new_img = str_replace( basename( $image_src[0] ), basename( $new_img_path ), $image_src[0] );

// resized output
$vt_image = array (
'url' => $new_img,
'width' => $new_img_size[0],
'height' => $new_img_size[1]
);

return $vt_image;
}

// default output - without resizing
$vt_image = array (
'url' => $image_src[0],
'width' => $image_src[1],
'height' => $image_src[2]
);

return $vt_image;
}



Call it like this:


thumb = vt_resize( $attachment->ID,'' , 150, 120, true, 70 );


PS: not tested.

2010-11-05

Denzel Chia answers:

Hi,

Do you remember the code I wrote for you to resize videos on this previous thread?
http://www.wpquestions.com/question/show/id/1020

You can always modify it to work with images, so that all of them have the same width, leaving or removing the height attribute so that image retains aspect ratio if it is a vertical image.

Let me know what you think.

Thanks.