Php WordPress-上传时模糊图像

Php WordPress-上传时模糊图像,php,wordpress,upload,blur,imagick,Php,Wordpress,Upload,Blur,Imagick,因此,我按照(我修改为只模糊,没有水印),在WordPress上传时制作模糊图像。问题是,如果上传的文件的大小与设置的大小完全相同或更小,WordPress将不会生成图像,因此不会产生模糊图像 我尝试使用isst($meta['size']['background-image-fuzzle']['file'])来确定是否制作了一个,如果没有,则copy()源文件,但不会为图像生成WordPress“元数据”(对于非WordPress用户,元数据与您想象的不同),因此,在使用wp\u get\u

因此,我按照(我修改为只模糊,没有水印),在WordPress上传时制作模糊图像。问题是,如果上传的文件的大小与设置的大小完全相同或更小,WordPress将不会生成图像,因此不会产生模糊图像

我尝试使用
isst($meta['size']['background-image-fuzzle']['file'])
来确定是否制作了一个,如果没有,则
copy()
源文件,但不会为图像生成WordPress“元数据”(对于非WordPress用户,元数据与您想象的不同),因此,在使用
wp\u get\u attachment\u image
显示时,会出现高度/宽度未定义的问题

因此,我确信使用如下所示的
wp\u get\u attachment\u image
hook可能是错误的方法。这可能需要在图像上传过程中更早地进行

关于如何最好地让它工作,有什么想法吗

/**
 * Several functions relatting to blurring images on uploaded.
 * @see https://codeable.io/community/how-to-watermark-wordpress-images-with-imagemagick/
 */ 
    add_image_size( 'background-image-blurred', 1920, 1080, true );

    function generate_blurred_image( $meta ) {

      $time = substr( $meta['file'], 0, 7); // Extract the date in form "2015/04"
      $upload_dir = wp_upload_dir( $time ); // Get the "proper" upload dir

      $filename = $meta['sizes']['background-image-blurred']['file'];
      $meta['sizes']['background-image-blurred']['file'] = blur_image( $filename, $upload_dir );

      return $meta;

    }
    add_filter( 'wp_generate_attachment_metadata', 'generate_blurred_image' );    

    function blur_image( $filename, $upload_dir ) {

      $original_image_path = trailingslashit( $upload_dir['path'] ) . $filename;

      $image_resource = new Imagick( $original_image_path );
      $image_resource->gaussianBlurImage( 10, 100 ); // See: http://phpimagick.com/Imagick/gaussianBlurImage

      return save_blurred_image( $image_resource, $original_image_path );

    }    

    function save_blurred_image( $image_resource, $original_image_path ) {

      $image_data = pathinfo( $original_image_path );

      $new_filename = $image_data['filename'] . '-blurred.' . $image_data['extension'];

      // Build path to new blurred image
      $blurred_image_path = str_replace($image_data['basename'], $new_filename, $original_image_path);

      if ( ! $image_resource->writeImage( $blurred_image_path ) ) {
        return $image_data['basename'];          
      }

      // Delete the placeholder image WordPress made now that it's been blurred
      unlink( $original_image_path );

      return $new_filename;

    }    

我想你需要耍点小把戏,为什么你不尝试使用大小为1x15x5的图像,所以无论图像是什么,每次都会生成该图像的缩略图

“wp\u生成附件\u元数据”时,对原始图像进行黑客攻击并生成图像,然后用模糊图像替换1 x 1图像,您需要在任何地方使用“背景图像模糊”进行过滤显示或其他计算用途


希望您能理解我的想法,我认为这有点像黑客,但应该可以正常工作。

专注于功能如何


当我第一次阅读你的问题时,我不确定你是否在设置图像或生成图像或两者都有问题。我认为设置图像的问题可能是,在使用
wp\u update\u attachment\u metadata
后,您需要使用
wp\u generate\u attachment\u metadata
更新帖子图像,让帖子改用新图像

当我重读你的问题时,我意识到这一定是
添加图像大小()的问题,因为它发生在与上载图像大小相同或更小的图像上。我曾经遇到过这个问题,因为(重新)为一个新主题生成了一个备用大小的图像。在我的例子中,是因为在
add\u image\u size()
上未满足宽度或高度参数

我想在中验证这一点,并在底部附近找到了一位撰稿人的评论,该评论与您面临的问题完全相同,尽管没有发布解决方案

如果上载尺寸与“添加图像大小”()匹配的图像 当crop设置为true时,在由 wp_生成_附件_元数据过滤器,匹配的图像大小将 没有。此外,尺寸大于的图像大小 上传的照片也将不可用

(因此,如果您使用一种技术来创建类似 单色导数图像,如果 上传的图像大小与您正在上传的图像大小完全相同 用于您的黑白版本)

我认为在你的例子中,有一个解决方案,因为你使用Imagick,事实上你可以做一些图像数学。使用
borderImage
功能,只需为每个图像添加一个边框,该边框比您上传的图像大1个像素。由于默认情况下,
add\u image\u size()
会从中心裁剪,这将触发调整大小到所需大小,并解决问题

例如,您需要1920 x 1080的尺寸。使用Imagick
getSize
可以检查图像的大小。假设它正好是1920 x 1080,但我们知道这不会触发模糊。因此,我们使用
borderImage
为图像添加一个1像素的白色边框。这将触发wordpress将图像大小调整为1920 x 1080,只要crop设置为true

如果图像较小,但相对接近所需大小,我们只需制作边框,比如说10个像素,依此类推以填充大小,然后让wordpress从中心裁剪。这仅适用于比例图像


如果图像是一个好一点的小,让我们说200×800,我们应该考虑添加一个不同的<代码> AddiaIMAGE()/<代码>选项来处理较小的图像。如果您需要继续前进,那么我们可以使用Imagick将图像“扩展”到所需的比例,或者我们可以创建一个新的白色Imagick画布,该画布的大小符合我们的需要,并将图像覆盖到左上角,以便在新图像的右下角有空白。然后使用“添加图像大小”裁剪参数来切断多余的白色。例如,

add_image\u size('background-image-fuzzle',1920,1080,array('left','top'))
从图像的左上角开始设置裁剪。

一个开箱即用的建议:由于您只是模糊图像,而没有对图像进行任何其他更改,为什么不让CSS做腿部工作,而不是在服务器上创建另一个图像

.heroBackgroundImage {
    background: url('uploadedimage.jpg'); 
    -webkit-filter: blur(8px);
    -moz-filter: blur(8px); 
    -o-filter: blur(8px); 
    -ms-filter: blur(8px); 
    filter: blur(8px);
    -webkit-transform: translate3d(0,0,0);
}
节省服务器的工作量;让它在客户端处理


编辑:刚刚看到你对它的评论不能是CSS。添加webkit变换以将效果移动到GPU,使其渲染更高效。否则,仍将为后代保存。

不幸的是,wp没有强制设置大小的过滤器,因此您可以在创建图像后挂接图像,调整图像大小,并将其弹出到元数据中

我没有imagick,所以您必须自己尝试这些函数,但是您有上面的正确过程,您只需要更新文件名并在下面的数组中键入。PS不要在过滤器内输出任何内容

function custom_img_size(){
    add_image_size( 'background-image-blurred', 1920, 1080, true );
}

add_action( 'after_setup_theme', 'custom_img_size' );


add_filter('wp_generate_attachment_metadata', 'force_add_size', 100);
function force_add_size( $metadata ) {

   if(!isset($metadata['sizes']['background-image-blurred'])){
        //not set so initiate our custom size...
        //I dont have imagick installed so just use your functions here to duplicate
        //note original file = $filename update the $newfilename below...
        //sample resize code ...
        $upload_dir = wp_upload_dir();
        $filename= $upload_dir['basedir'].'/'.$metadata['file'];
        $extension = strtolower(strrchr($metadata['file'], '.'));
        $newfilename= str_replace($extension, '-1200x1080', $filename).$extension;

        copy($filename, $newfilename );
        //end sample resize code.....



        $filetype= 'image/jpeg';
        $metadata['sizes']['background-image-blurred']= array(
            "file"=> $newfilename,
            "width"=> 1920, 
            "height"=> 1080,
            "mime-type"=> $filetype 
        );

   }


   return $metadata;

}
更新

  • 这是为了只捕获现有过滤器出现故障的地方
    add_filter('wp_generate_attachment_metadata', 'force_add_size', 100, 2);
    
    function force_add_size( $metadata, $id ){
    
        $upload_dir = wp_upload_dir();
        $filename= $upload_dir['basedir'].'/'.$metadata['file'];
        $extension = strtolower(strrchr($metadata['file'], '.'));
        $newfilename= str_replace($extension, '-blurred', $filename).$extension;
    
        $image_resource = new Imagick( $filename);
        $image_resource->resizeImage(1920,1080,Imagick::FILTER_LANCZOS,.3);
        $image_resource->writeImage( $newfilename );
        //http://www.dylanbeattie.net/magick/filters/result.html
    
        unlink( $filename );//delete original image altogether ---> you might want to update the post meta on this '_wp_attached_file' , you can actually get the attachment id from the filter, i have added it above. It would be best to have a actual image url in there! something like $sfile= str_replace($upload_dir['basedir'],'', $newfilename); update_post_meta($id, '_wp_attached_file', $sfile );
    
    
    
        switch($extension){
            case '.jpg':
            case '.jpeg':
                $type = 'image/jpeg';
                break;
            case '.gif':
                $type = 'image/gif';
                break;
            case '.png':
                $type = 'image/png';
                break;
            default:
                $type = 'image/jpeg'; // you might want a conditional to check its actually a image...imagick will do this for you as well....it shouldnt get this far if not a image.
                break;
        } 
    
        $metadata['sizes']['background-image-blurred']= array(
            "file"=> $newfilename,
            "width"=> 1920,//your custom image size, has to be this! you could get the global var and check for sizes but its this size in particular we want? 
            "height"=> 1080,
            "mime-type"=> $type 
        );
    
        return $metadata;
    }
    
    $upload_dir = wp_upload_dir();
    $filename= $upload_dir['basedir'].'/'.$metadata['file'];
    $extension = strtolower(strrchr($metadata['file'], '.'));
    $newfilename= str_replace($extension, '-blurred', $filename).$extension;
    
    $image_resource = new Imagick( $filename);
    
    
    if($image_resource->getImageWidth() <= 1920 || $image_resource->getImageHeight() > <= 1020) {
        return $metadata;
    }
    
    $image_resource->resizeImage(1920,1080,Imagick::FILTER_LANCZOS,.3);
    $image_resource->writeImage( $newfilename );
    //http://www.dylanbeattie.net/magick/filters/result.html
    
        // perform new upload
        include_once( ABSPATH . 'wp-admin/includes/image.php' );
        $imagetype = end(explode('/', getimagesize($imageurl)['mime']));
        $uniq_name = date('dmY').''.(int) microtime(true); 
        $filename = $uniq_name.'.'.$imagetype;
    
        $uploaddir = wp_upload_dir();
        $uploadfile = $uploaddir['path'] . '/' . $filename;
        $contents= file_get_contents($imageurl);
        $savefile = fopen($uploadfile, 'w');
        fwrite($savefile, $contents);
        fclose($savefile);
    
        // apply blur
        $image_resource = new Imagick( $uploadfile );
        $image_resource->resizeImage(500, 500, null, 1);
        $image_resource->blurImage( 40, 20 );
        $image_data = pathinfo( $uploadfile );
    
        $new_filename = $image_data['filename'] . '-blur.' . $image_data['extension'];
        $blur_image_path = str_replace($image_data['basename'], $new_filename, $uploadfile);
        if ( ! $image_resource->writeImage( $blur_image_path ) ) {
            unlink( $uploadfile );
            return ""; // fixme
        }
    
        unlink( $uploadfile );
    
        $wp_filetype = wp_check_filetype(basename($filename), null );
        $attachment = array(
            'post_mime_type' => $wp_filetype['type'],
            'post_title' => $imageurlHash,
            'post_content' => '',
            'post_status' => 'inherit'
        );
    
        $attach_id = wp_insert_attachment( $attachment, $blur_image_path );
        $imagenew = get_post( $attach_id );
        $fullsizepath = get_attached_file( $imagenew->ID );
        $attach_data = wp_generate_attachment_metadata( $attach_id, $fullsizepath );
        wp_update_attachment_metadata( $attach_id, $attach_data );