I am trying to get an image from the private folder to display on a printer-friendly Twig template page. The private folder is inaccessible to browsers and the only display method I know of is to load the image and convert it to Base64 and pass the Base64 characters into the 'src' attribute of an 'img' element.
My controller code looks something like this:
class PrinterFriendlyController extends ControllerBase {
public function printerFriendly($text) {
// Load image from private directory and convert to base64
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$image = $this->entityTypeManager
->getStorage('file')
->load($file_id);
$image_path = PrivateStream::basePath() . '/images/' . $image->getFilename();
$image_data = file_get_contents($image_path);
$image_base64 = 'data:' . finfo_file($finfo, $image_path) . ';base64,' . base64_encode($image_data);
$page = [
// Definitely longer than 255 characters
'#image_base64' => $image_base64,
// This doesn't work either so it's not a character length issue
//'#image_base64' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==',
'#text' => $text,
'#theme' => 'printer_friendly',
];
return $page;
}
}
The template file looks something like this:
<div id="printer-friendly">
<img src="{{ image_base64 }}" />
<div id="text">{{ text }}</div>
</div>
The 'text' element contains custom text that is positioned over the 'img' element using CSS but is only included for context. It's not related to the problem.
The result that appears on Chrome Inspect is:
<img src="">
or
<img src(unknown)>
Either Drupal or Twig is blocking the Base64 image characters but I don't know which one is doing the blocking and I don't know how to prevent it from doing so.