按需要生成图片缩略图

以前有段时间没有使用WordPress是因为WP的图片策略实在难以让人接受,不管图片是否有需要,它都会自动把每一张图片生成不同尺寸的缩略图。对于普通博客作者来说,虽然在空间上不会造成压力。但有强迫症的人就难以接受。另外就是对于图片博客作者来说就非常不友好了,会造成大量的空间浪费。

在按WP为构架打造自己的外贸网站时,因为用到的图片比较多,所以在上传的时候,WordPrss会不停地在后台把所有尺寸缩略都都生成了。这样的做的坏处是:

  • 如果一次性上传的图片太多,需要大量的时间生成缩略图,等待图片上传是一种折磨
  • 生成了很不必要的缩略图,浪费空间是肯定的。
  • 图片太多,不方便管理
  • 图片太多,对于有些代码调用图片会增加服务器计算时间

鉴于上述原因,故Google好一会,重新汇编了以下代码优化了WordPress图片上传,实现了按需要生成缩略图,不需要的则不生成缩略图。以下代码有以下个特点:

  • 禁用了图片上传时生成缩略图。是的,一张缩略图也不会生成
  • 因此,如果使用特色缩略图post-thumbnail,必须要手动生成,推荐配合crop-thumbnails插件可以调整图片切片效果
  • 在主题模板调用时,会自动生成对应的缩略图。不需要的尺寸,则不会自动生成。
  • 待解决问题:可能没有研究透彻,WordPress预留的默认图片格式'thumbnail', 'medium', 'medium_large', 'large'都不能使用,因为一旦启用,在图片上传时,就会自动生成缩略图。望高手指教。

第一:重新设置图片尺寸

因为WordPress预留的默认图片格式'thumbnail', 'medium', 'medium_large', 'large'都没办法启动,所以必须要禁用掉,只能使用add_image_size去设置新的图片名称和尺寸。

function cq_image_init() {
	// Revise default Images sizes in media setting
	update_option( 'thumbnail_size_w', 0 );
    update_option( 'thumbnail_size_h', 0 );
	update_option( 'thumbnail_crop', 0 );
	update_option( 'medium_size_w', 0 );
    update_option( 'medium_size_h', 0 );
	update_option( 'medium_large_size_w', 0 );
    update_option( 'medium_large_size_h', 0 );
	update_option( 'large_size_w', 0 );
    update_option( 'large_size_h', 0 );
	
	// Add Feature image
	add_theme_support( 'post-thumbnails' );	
	set_post_thumbnail_size( 800, 250, true );
	
	add_image_size( 'aside-thumb', 0, 300 );
}
add_action( 'after_setup_theme', 'cq_image_init' );

上述代码,默认将所有系统默认的图片格式尺寸全部禁用,也就是在后台>媒体中,所有图片格式尺寸都已经自动归零。同时设置了特色缩略图尺寸和一个新的自定义尺寸。

第二:禁止后台上传图片时,自动生成缩略片

虽然第一步已经将默认的图片格式尺寸全部归零,但新设置的特色缩略图和自定义图片尺寸仍然会将每一张图片自动生成缩略图片,必须使用以下代码禁止自动生成。

//Disabling auto-generate resizing images when upload in editor
function cq_media_disable_auto_resizing_on_upload( $sizes, $metadata ) {
    return []; 					     // diable all
	//unset($sizes['thumbnail']);    // disable thumbnail size
	//unset($sizes['medium']);       // disable medium size
	//unset($sizes['large']);        // disable large size
	//unset($sizes['medium_large']); // disable medium-large size
	//unset($sizes['1536x1536']);    // disable 2x medium-large size
	//unset($sizes['2048x2048']);    // disable 2x large size
	//remove_image_size('post-thumbnail'); // disable images added via set_post_thumbnail_size() 
	//remove_image_size('another-size');   // disable any other added image sizes	
	//return $sizes;
}
add_filter( 'intermediate_image_sizes_advanced', 'cq_media_disable_auto_resizing_on_upload', 10, 2 );
add_filter( 'big_image_size_threshold', '__return_false' );	

上面使用了最粗暴的方法return []来禁用所有图片自动生成。也可以采用注释过的按指定尺寸禁用。

第三:按需要生成指定尺寸的图片缩略图

直接上代码

/* Filter image resizing, only generate when on-the-fly
** What is on-the-fly: NOT generate revising images, only start generating resizing images when the_post_thumbnail('your-specified-image-size') in template
** 
** Since 'thumbnail', 'medium', 'medium_large', 'large' are NOT work on-the-fly
** So all default WordPress image sizes will be disabled, only use customized image name.
*/
add_filter( 'image_downsize', 'cq_image_downsize', 10, 3 );
function cq_image_downsize( $out, $id, $size ) {

	if ( is_array( $size ) ) return false;

	$wanted_width = $wanted_height = 0;
	
	$meta = wp_get_attachment_metadata( $id );
	if ( empty( $meta['file'] ) ) return false;		
	
	global $_wp_additional_image_sizes;
	// generate post-thumbnail, size from add_image_size
	if ( isset( $_wp_additional_image_sizes ) && isset( $_wp_additional_image_sizes[ $size ] ) ) {
		$wanted_width = $_wp_additional_image_sizes[ $size ]['width'];
		$wanted_height = $_wp_additional_image_sizes[ $size ]['height'];
		$wanted_crop = isset( $_wp_additional_image_sizes[ $size ]['crop'] ) ? $_wp_additional_image_sizes[ $size ]['crop'] : false;
	
	// generate revised files if they have set up size in editor.
	//} else if ( in_array( $size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
	//	$wanted_width  = get_option( $size . '_size_w' );
	//	$wanted_height = get_option( $size . '_size_h' );
	//	$wanted_crop   = ( 'thumbnail' === $size ) ? (bool) get_option( 'thumbnail_crop' ) : false;

	} else {
		return false;
	}	
		
	if ( 0 === absint( $wanted_width ) && 0 === absint( $wanted_height ) ) {
		return false;
	}

	if ( $intermediate = image_get_intermediate_size( $id, $size ) ) {
		$img_url = wp_get_attachment_url( $id );
		$img_url_basename = wp_basename( $img_url );

		$img_url = str_replace( $img_url_basename, $intermediate['file'], $img_url );
		$result_width = $intermediate['width'];
		$result_height = $intermediate['height'];

		return array(
		  $img_url,
		  $result_width,
		  $result_height,
		  true,
		);
		
	} else {
        // image size not found, create it
		$attachment_path = get_attached_file( $id );
		$image_editor = wp_get_image_editor( $attachment_path );

		if ( ! is_wp_error( $image_editor ) ) {
		  $image_editor->resize( $wanted_width, $wanted_height, $wanted_crop );
		  $result_image_size = $image_editor->get_size();

		  $result_width = $result_image_size['width'];
		  $result_height = $result_image_size['height'];

		  $suffix = $result_width . 'x' . $result_height;
		  $filename = $image_editor->generate_filename( $suffix );

		  $image_editor->save( $filename );

		  $result_filename = wp_basename( $filename );

		  $meta['sizes'][ $size ] = array(
			'file'      => $result_filename,
			'width'     => $result_width,
			'height'    => $result_height,
			'mime-type' => get_post_mime_type( $id ),
		  );

		  wp_update_attachment_metadata( $id, $meta );

		  $img_url = wp_get_attachment_url( $id );
		  $img_url_basename = wp_basename( $img_url );

		  $img_url = str_replace( $img_url_basename, $result_filename, $img_url );

		  return array(
			$img_url,
			$result_width,
			$result_height,
			true,
		  );

		} else {
		  return false;
		}	
	}
}

上面第一步提到的问题点就是下面这些代码,一旦启用,它就会自动生成WordPress默认的图片格式尺寸,也就达不到我们想要的预期目的了,所以我就直接禁用了。

	// generate revised files if they have set up size in editor.
	//} else if ( in_array( $size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
	//	$wanted_width  = get_option( $size . '_size_w' );
	//	$wanted_height = get_option( $size . '_size_h' );
	//	$wanted_crop   = ( 'thumbnail' === $size ) ? (bool) get_option( 'thumbnail_crop' ) : false;

第四:使用方法

我们在主题模板中,使用的方法很简单,如果是调用特色缩略post-thumbnail,直接使用以下代码

<?php the_post_thumbnail( ); ?>

而如果是调用自定义尺寸图片的缩略图,则使用以下代码

<?php the_post_thumbnail( 'aside-thumb' ); ?>

完毕。

希望后续能解决如果保留WordPress系统默认格式的尺寸缩略图。

« WordPress主题自定义customizer增加多个复选框 按需要生成图片缩略图(更新) »

Say Something!

Leave a Reply