WordPress - 上传时模糊图像

     2023-02-24     66

关键词:

【中文标题】WordPress - 上传时模糊图像【英文标题】:WordPress - Blur Image on Upload 【发布时间】:2016-03-26 10:31:26 【问题描述】:

所以我正在关注example given here(我将其修改为仅模糊,无水印),以便在上传时在 WordPress 中制作模糊图像。问题是,如果上传的文件大小完全相同,或者小于设置的大小,那么 WordPress 将不会生成图像,因此不会产生模糊的图像。

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

所以我确信使用如下所示的wp_get_attachment_image 钩子可能是错误的方法。它可能需要在图像上传过程的早期发生。

关于如何最好地完成这项工作的任何想法?

/**
 * 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;

        

【问题讨论】:

仅供参考,它必须是服务器端模糊。我厌倦了 CSS/SVG/JS 模糊,考虑到我正在进行的所有其他动画,它的效率还不够。 “问题是,如果上传的文件大小完全相同,或者小于设置的大小”我不确定是否完全正确地理解这一点,您正在尝试替换现有图片? 不,我正在尝试生成上传文件的新模糊版本。与wp_generate_attachment_metadata 相关的评论只有在制作新版本时才会被调用(如果尺寸太小或相同,则不会产生任何新内容)。 【参考方案1】:

不幸的是,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;


更新

    这旨在仅捕获现有过滤器未能创建模糊自定义尺寸的地方,否则它什么也不做。您仍应包含原始过滤器。您可能在原始代码中遇到问题:您正在删除过滤器中的原始文件,这将导致问题,因为有一个名为“_wp_attached_file”的 postmeta 字段需要更新。我在下面附上了一个注释。

    过滤器会在保存之前捕获元数据,因此一旦您返回 $metadata,任何更改也将被保存。如果你查看源代码:https://core.trac.wordpress.org/browser/tags/3.8.1/src/wp-admin/includes/image.php#L72 这里你可以确切地看到它是如何工作的。我也确认使用 wp4.3

    我试图在下面插入您需要的 imagick 函数。我没有测试过,因为我实际上并没有将它安装在任何地方。 (imagemagick 实际上是一个很棒的开源程序,但服务器非常密集)。试试这个函数来代替上面的那个:

    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;
    
    

更新 为防止图像拉伸较小的图像,请用此替换 imagick 代码。

$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

【讨论】:

我认为这可能是要走的路。不是一个完整的答案,但我在 7 天的赏金期内最好的答案。 你觉得缺少什么,生病看看? 嗯,我不是 100% 知道 Imagick 代码需要去哪里,而且图像并不总是image/jpeg 对吗?而且您将高度/宽度硬编码为1920x1080,它可能并不总是这样(并且也将-1200x1080 添加到文件名中。另外,我认为wp_generate_attachment_metadata 过滤器在创建元数据后运行,所以新的模糊图像不会将其元数据正确添加到数据库中(我想,我需要测试一下)。 大卫,这似乎有效,除了它也删除了原始图像。我需要非模糊和模糊图像。有什么想法吗? 我注释掉了unlink,它起作用了,但似乎模糊图像和非模糊图像之间的纵横比发生了变化。【参考方案2】:

当我第一次阅读您的问题时,我不确定您是否在设置图像或生成图像时遇到问题,或两者兼而有之。我认为设置图像的问题可能是您需要在使用wp_generate_attachment_metadata 之后使用wp_update_attachment_metadata 更新帖子图像才能让帖子使用新图像。

当我重新阅读您的问题时,我意识到这一定是add_image_size() 的问题,因为它发生在与上传的图像大小相同或更小的图像上。我曾经遇到过这个问题,以及(重新)为新主题生成备用尺寸图像。在我的情况下,add_image_size() 上没有满足宽度或高度参数。

我想在Wordpress Code Reference 中验证这一点,并在底部附近找到了一位贡献者的评论,这与您面临的问题完全相同,尽管没有发布解决方案。

如果您上传的图片尺寸与 add_image_size() 当crop设置为true时,在$meta对象访问的 wp_generate_attachment_metadata 过滤器,匹配的图像大小将 不可用。此外,尺寸大于 上传的照片也将不可用。

(因此,如果您使用一种技术来创建类似 单色衍生图像,如果 上传的图片与您的图片尺寸完全相同 用于您的黑白版本)。

我认为在您的情况下,由于您使用的是 Imagick,因此有一个解决方案,事实上您可以进行一些图像数学运算。使用borderImage 函数只需为每个图像添加一个边框,该边框最多比您上传的图像大 1 像素。由于add_image_size() 默认从中心裁剪,这应该会触发将大小调整为您需要的大小并解决问题。

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

如果图像较小但相对接近所需大小,我们只需将边框设为 10 像素等以填充大小,然后让 wordpress 从中心裁剪。这仅适用于比例图像。

如果图像小一点,比如 200 x 800,我们应该考虑添加一个不同的 add_image_size() 选项来处理较小的图像。如果您需要继续前进,那么我们可以使用 Imagick 将我们的图像“扩展”到所需的比例,或者我们可以创建一个我们需要的新的白色 Imagick 画布并将图像覆盖到左上角,这样我们下面就有了空白并我们的新形象的权利。然后,您将使用 add_image_size 裁剪参数来切断多余的白色。例如,add_image_size('background-image-blurred', 1920, 1080, array('left','top')) 设置从图像左上角开始裁剪。

【讨论】:

好主意,但我认为它创建了很多步骤只是为了绕过一些 WordPress 限制。我为这项努力投了赞成票!【参考方案3】:

我认为您需要花点心思,为什么您不尝试使用 1 x 15 X 5 大小的图像,所以每次无论什么时候图像会生成该图像的缩略图。

'wp_generate_attachment_metadata' 破解材料并从原始图像生成图像并将 1 x 1 图像替换为您想要的模糊图像如果您在任何地方使用 'background-image-blurred' 进行显示或其他计算目的,您需要欺骗过滤器。

希望你明白我认为这有点 hack 但应该可以正常工作。

【讨论】:

【参考方案4】:

关注wp_handle_upload()函数怎么样?

Here is an example 如何使用它来模糊图像。

【讨论】:

是的,很好的提示。你知道wp_handle_upload是否在wp_generate_attachment_metadata之前被调用? 如果你用 wp_handle_upload() 上传 orig img...模糊它...然后在模糊的 img 上调用 wp_generate_attachment_metadata 怎么办? 你试过我的建议了吗? 一直在尝试,但很难将其转化为我的情况(作为所有上传的过滤器)。这不是一个真正的直接答案,它更像是一个建议,有帮助,但我希望得到更详细的内容。【参考方案5】:

一个开箱即用的建议:既然您只是模糊图像而不对图像进行任何其他更改,为什么不让 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-transform 以将效果移动到 GPU,使其渲染效率更高。否则,仍然为后代保存。

【讨论】:

【参考方案6】:

您所指的示例使用了 wordpress 过滤器。

问题是:wordpress 过滤器总是绑定到特定的图像分辨率,因此无论分辨率如何,您都无法处理图像。

我的建议是避免使用过滤器。而是在较早的时间点对图像进行预处理。请在下面找到一个示例代码,该代码最初会在将控制权交给 wordpress 之前模糊图像:

    // 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 ); 

【讨论】:

php[自定义图像尺寸]添加自定义尺寸图像(上传媒体时的新尺寸)#wordpress#php(代码片段)

查看详情

Wordpress:上传时出错

】Wordpress:上传时出错【英文标题】:Wordpress:Anerroroccurredintheupload【发布时间】:2013-01-2322:15:16【问题描述】:更新到WordPress3.5后,我在以非管理员用户身份使用“添加媒体”按钮上传文件时开始收到以下错误:错误:上传时出... 查看详情

敏捷上传器 Wordpress 实现

】敏捷上传器Wordpress实现【英文标题】:AgileUploaderWordpressimplementation【发布时间】:2012-11-3005:23:48【问题描述】:我正在尝试实现一个首页Wordpress上传器,它使用户可以从Wordpress页面上传图像,并在上传之前调整图像大小。我找... 查看详情

使用 Elastic BeanStalk 安装的 Wordpress 会覆盖上传的图像

】使用ElasticBeanStalk安装的Wordpress会覆盖上传的图像【英文标题】:WordpressinstalledwithElastickBeanStalkoverwritesuploadedimages【发布时间】:2015-02-0916:10:17【问题描述】:我在AmazonElasticBeanStalk上有Wordpress实例。当我用EB脚本上传实例时,... 查看详情

新安装 Wordpress 3.9 抛出错误:上传图像时“无法创建目录 wp-content/uploads/2014/09”

】新安装Wordpress3.9抛出错误:上传图像时“无法创建目录wp-content/uploads/2014/09”【英文标题】:NewinstallWordpress3.9isthrowingerror:"Unabletocreatedirectorywp-content/uploads/2014/09"whenuploadinganimage【发布时间】:2014-09-0122:47:15【问题描述... 查看详情

将图像从github上传到wordpress网站(代码片段)

我是网站开发的新手,我正在使用WordPress创建一个网站来上传实时预测结果。结果从特定位置的现场设备收集,该模型应运行并每4小时上载到GitHub。每当新图像可用时,先前的数据将被下一个数据替换。问题是我正在尝试将这... 查看详情

wordpress上传过程中的文件重命名功能

】wordpress上传过程中的文件重命名功能【英文标题】:Filerenamingfunctionsinwordpressuploadprocess【发布时间】:2012-11-0413:59:23【问题描述】:我有一个脚本,它可以从预定义的数组中自动加载帖子,并将图像作为特色图像从本地计算机... 查看详情

Wordpress 媒体上传器无法正确上传

】Wordpress媒体上传器无法正确上传【英文标题】:Wordpressmediauploadernotuploadingproperly【发布时间】:2012-09-0413:38:27【问题描述】:我正在通过Wordpress媒体上传器上传媒体。它说它可以很好地上传文件(如果我检查我的上传文件夹,... 查看详情

WordPress 坐在虚拟主机配置上时无法上传图像

】WordPress坐在虚拟主机配置上时无法上传图像【英文标题】:CannotuploadimageswhenWordPressissatonavirtualhostconfiguration【发布时间】:2011-05-2701:09:37【问题描述】:这是我在这个论坛上的第一篇帖子,如果其他地方已经回答了这个问题,... 查看详情

php自定义字段与上传图像选项-wordpress(代码片段)

查看详情

Wordpress 使用自定义端点 rest api 上传多个图像(离子作为最终用户)

】Wordpress使用自定义端点restapi上传多个图像(离子作为最终用户)【英文标题】:Wordpressuploadmultipleimageusingcustomendpointrestapi(ionicasenduser)【发布时间】:2019-04-2708:24:07【问题描述】:我想使用ionic(angularjs)将多张图片上传到wordpress... 查看详情

php自动将alt标签添加到wordpress图像上传(代码片段)

查看详情

如何将图像添加到wordpress中的每个类别?

】如何将图像添加到wordpress中的每个类别?【英文标题】:howtoaddimagetoeachcategoryinwordpress?【发布时间】:2011-01-2000:16:42【问题描述】:我创建插件以将图像添加到每个类别,我想在添加类别和编辑类别时上传图片,同样在类别列... 查看详情

php[将图像上传到媒体库]将图像上传到媒体库并将其设置为$post_id(如果已指定)的特色图像。#wordpress(代码片段)

查看详情

如何使用 wordpress 上的 update_field 在 ACF 上上传图像

】如何使用wordpress上的update_field在ACF上上传图像【英文标题】:howtouploadanimageonACFwithupdate_fieldonwordpress【发布时间】:2013-03-1607:20:42【问题描述】:我有一个表单,其中有一个上传($_FILES[\'watch_photo\'])字段。我环顾四周,来把这... 查看详情

WordPress:“HTTP 错误。”上传文件时

】WordPress:“HTTP错误。”上传文件时【英文标题】:Wordpress:"HTTPError."WhenUploadingFiles【发布时间】:2011-05-0417:07:09【问题描述】:我正在使用PHP5在共享主机上运行WP3.0.1。我在通过WP管理部分的媒体上传器上传稍大一点的... 查看详情

Wordpress 自定义元框多张图片上传

】Wordpress自定义元框多张图片上传【英文标题】:Wordpresscustommetaboxmultipleimageupload【发布时间】:2016-08-2523:08:07【问题描述】:我正在使用添加了自定义元框的自定义帖子类型。在自定义元框中,我正在尝试为多个图像添加媒体... 查看详情

php根据当前注册的图像尺寸(wordpress),根据最小高度自动限制最小上传尺寸(代码片段)

查看详情