Drupal 8 图片与图像样式

27
在Drupal 8中,您需要使用ImageStyleInterface::buildUrl()函数来生成带有样式的新图像并返回其路径。
7个回答

63

根据变更记录

use Drupal\image\Entity\ImageStyle;

$path = 'public://images/image.jpg';
$url = ImageStyle::load('style_name')->buildUrl($path);

1
我需要在Twig模板中完成这个任务,但是我不能使用PHP。我该怎么做? - Fred K
3
@FredK,你的看法有些错误:你不一定需要在模板中这样做;也许出于某种原因你想这么做,但这是一个不好的想法,而且你确实不必这么做。这段代码最好放在模板预处理函数中。但如果你坚持要在Twig中完成,你需要编写一些PHP代码将 ImageStyle 类方法暴露给Twig。然而,这比按照建议的方式完成要花费更长的时间。 - Clive
1
对于仍在寻找@FredK解决方案的人,Twig Tweak模块具有image_style过滤器,可用于避免预处理。 - Clive

18

您应该尽可能使用新的Drupal函数。

而不是使用:

use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;

$fid = 123;
$file = File::load($fid);
$image_uri = ImageStyle::load('your_style-name')->buildUrl($file->getFileUri());

根据https://www.drupal.org/node/2050669的编辑:

$original_image = 'public://images/image.jpg';

// Load the image style configuration entity
use Drupal\image\Entity\ImageStyle;
$style = ImageStyle::load('thumbnail');

$uri = $style->buildUri($original_image);
$url = $style->buildUrl($original_image);

9

在 Drupal 的控制器和其他面向对象编程部分中,您可以使用:

use Drupal\image\Entity\ImageStyle;

$path = 'public://images/image.jpg';
$url = ImageStyle::load('style_name')->buildUrl($path);

YOUR_THEME.theme 文件中,当出现 Error: Class 'ImageStyle' not found in YOURTHEMENAME_preprocess_node 错误时,您可以使用以下方法进行处理:

 $path = 'public://images/image.jpg';
 $style = \Drupal::entityTypeManager()->getStorage('image_style')->load('thumbnail');
 $url = $style->buildUrl($path);

另一种方法是提供一个可渲染的数组,让 Drupal 的渲染引擎进行渲染。
$render = [
    '#theme' => 'image_style',
    '#style_name' => 'thumbnail',
    '#uri' => $path,
    // optional parameters
];

感谢提供三个版本! - Patrick Janser

2

我发现我经常想要对节点或段落类型中的图片进行预处理,以应用图像样式。在许多情况下,我创建了一个段落,允许用户选择图像宽度的百分比。在预处理中,我会检查宽度的值并应用正确的图像样式。

use Drupal\image\Entity\ImageStyle;

function THEME_preprocess_paragraph__basic_content(&$vars) {
  //get the paragraph
  $paragraph = $vars['paragraph'];

  //get the image
  $images = $paragraph->get('field_para_image');
  //get the images value, in my case I only have one required image, but if you have unlimited image, you could loop thru $images
  $uri = $images[0]->entity->uri->value;

  //This is my field that determines the width the user wants for the image and is used to determine the image style
  $preset = $paragraph->get('field_column_width')->value;

  $properties = array();
  $properties['title'] = $images[0]->getValue()['title'];
  $properties['alt'] = $images[0]->getValue()['alt'];

  //this is where the Image style is applied
  switch($preset) {
     case 'image-20':
       $properties['uri'] = ImageStyle::load('width_20_percent')->buildUrl($uri);
       break;
     case 'image-45':
       $properties['uri'] = ImageStyle::load('width_45_percent')->buildUrl($uri);
       break;
     case 'image-55':
       $properties['uri'] = ImageStyle::load('width_55_percent')->buildUrl($uri);
       break;
     case 'image-100':
       $properties['uri'] = ImageStyle::load('width_100_percent')->buildUrl($uri);
       break;
  }
  //assign to a variable that the twig template can use
  $vars['basic_image_display'] = $properties;
}

在这个例子中,我正在预处理一个名为“basic_content”的特定段落类型,但是您也可以使用节点预处理来完成相同的操作。继续我的例子,我将拥有一个名为paragraph--basic_content.html.twig的twig模板来处理该段落类型的显示。
在twig文件中,显示图像类似于以下内容。
<img class="img-responsive" src="{{basic_image_display['uri']}}" alt="{{ basic_image_display['alt'] }}" title="{{ basic_image_display['title'] }}"/>

1
$view_mode = $variables['content']['field_media_image']['0']['#view_mode'];
$display_content = \Drupal::service('entity_display.repository')
->getViewDisplay('media', 'image', $view_mode)->build($media_entity);
$style = ImageStyle::load($display_content['image'][0]['#image_style']); $original_image = $media_entity->get('image')->entity->getFileUri();
$destination = $style->buildUri($original_image);

这是获取媒体图片实体样式的方法。

你是不是假设这段代码需要放在特定的hook_preprocess函数中?例如,->build($media_entity)中的$media_entity是从哪里来的? - JDev518

0

在 .module 文件中,经典的 Drupal 数据库查询对我有效:

$query = \Drupal::database()->select('file_managed', 'f' );
$query->addField('f', 'uri');
$pictures = $query->execute()->fetchAll();

foreach ($pictures as $key => $picture) {

   $largePictureUri = entity_load('image_style', 'large')->buildUrl($picture->uri);
}

-1
我在Drupal 8中使用了这段代码。它正常工作。
$fid = 374; //get your file id, this value just for example 
$fname = db_select('file_managed', 'f')->fields('f', array('filename'))->condition('f.fid', $fid)->execute()->fetchField();
$url = entity_load('image_style', 'YOUR_STYLE_NAME')->buildUrl($fname);

1
最佳实践(以及更干净的代码)是使用 Drupal 对象而不是数据库查询。我建议使用 $file = File::load($fid); 命令获取文件对象,而不是为了查询文件名而查询数据库。 - sagesolutions
1
补充sagesolution的评论,entity_load()函数现已弃用,因此用户应参考使用ImageStyle类加载样式的答案。 - Sean Wickham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接