Jump to content

Thumbnails for Pagefiles


teppo
 Share

Recommended Posts

So... this may be a bit of a weird question, but does anyone have brilliant ideas for generating thumbnails for Pagefile (not Pageimage) objects?

A bit of background: in a recent project I ran into an issue with this in a situation where there's a files field that contains many different types of files, but for image files it needs to display thumbnails. The problem is that those images are Pagefiles, not Pageimages, so they don't have any image handling features built-in.

Current solution involves creating a new Pageimages object and a new Pageimage object, passing the image file to the Pageimage object... and hooking into the install method of said object to prevent duplicate file detection from actually spitting out an endless stream of duplicates. I did consider duplicating image files into another (hidden) field behind the scenes (did that in an even earlier project), but in the end neither solution seems particularly straightforward.

What's the state of the art approach for this? I've got this nagging feeling that there's something obvious I've missed ?

Link to comment
Share on other sites

41 minutes ago, teppo said:

I ran into an issue with this in a situation where there's a files field that contains many different types of files, but for image files it needs to display thumbnails.

I'm not quite sure if you mean thumbnails within the Files inputfield in the PW admin, or if you mean you want to resize the image file for the front-end. If it's the latter you could use a function or module method along these lines:

function getResizedImageUrl(Pagefile $pagefile, $width, $height) {
	$variation_basename = $pagefile->basename(false) . ".{$width}x{$height}." . $pagefile->ext();
	$variation_filename = $pagefile->pagefiles->path . $variation_basename;
	if(!is_file($variation_filename)) {
		copy($pagefile->filename, $variation_filename);
		$sizer = new ImageSizer($variation_filename);
		$sizer->resize($width, $height);
	}
	return $pagefile->pagefiles->url . $variation_basename;
}

$file = $page->files->first();
$resized_url = getResizedImageUrl($file, 400, 300);

 

  • Like 5
Link to comment
Share on other sites

Maybe useful for you @teppo. In one of my last projects I integrated a lightbox gallery that outputs both videos and pictures. The data source for the videos and images was a PageFile field. Here is an excerpt from the template in which the gallery was integrated via Javascript. Resizing works similarly as suggested by @Robin S
 

// galleries
$page->_galleriesJS = '';
$galleriePages = $pages->find('template=gallery');

// 16:9 inline video
$markup = '<div class="mfp-video-wrapper"><div class="mfp-video-inner"><video width="854" height="480" controls autoplay preload>
  <source src="{src}" type="video/mp4">
Leider wird dieses Video von ihrem Browser nicht unterstützt.
</video></div></div>';

if ($galleriePages->count) {
    $galleries = '';
    foreach ($galleriePages as $gp) {
        if ($gp->files->count == 0) continue;
        $items = [];
        $filesDirPath = $gp->files->path;
        foreach ($gp->files as $gi) {
            if (!fileExists($gi->url)) continue;
            
            // inline video
            if (in_array($gi->ext, array('mp4','m4v','ogg','ogv','mpg'))) {
                $src = str_replace('{src}', $gi->url, $markup);
                $items[] = ['type' => 'inline', 'src' => $src];
            }
            
            // wrong file type
            else if (!in_array($gi->ext, array('png','jpg','jpeg'))) throw new WireException("Unallowed Fileformat $gi->ext for magnificPopup Gallery");

            // any image with youtube video source in description
            else if (strpos($gi->description, 'youtube')) {    
                $oembed = getVideo($gi->description);
                if ($oembed) {
                    // nocookie source used            
                    $items[] = ['type' => 'iframe', 'src' => $oembed->frameUrl];
                }
            }

            // image
            else {
                $src = $gi->url;
                $copyFileName = strstr($gi->filename, $gi->ext, true) . '1200x0.' . $gi->ext;
                list($width, $height) = getimagesize($gi->filename);
                if ($width > 1200) {
                    if (!file_exists($copyFileName)) {
                        $files->copy($gi->filename, $copyFileName, ['limitPath' => true]);
                        $imageSizer = new ImageSizer($copyFileName);
                        $imageSizer->resize(1200, 0);
                    }
                    $src = str_replace($config->paths->root, '', $copyFileName);
                }
                $items[] = ['title' => $gi->description, 'src' => $src];
            }
        }

        $gallery = [
            'gallery' => ['enabled' => true],
            'type' => 'image',
            'midClick' => true,
             'mainClass' => 'mfp-lightbox-wrapper',
            'items' => $items,
            'tClose' => 'Schließen (esc)'
        ];

        $gallery = json_encode($gallery);
        $galleries .= "$('.mfp-open-$gp->id').magnificPopup({$gallery})\n";
    }

    $page->_galleriesJS = "<script>
    $galleries</script>
    ";
}

 

  • Like 5
Link to comment
Share on other sites

Awesome, thanks @Robin S and @kixe!

Manually copying the file and using ImageSizer on it seems like a really nice approach. Don't think I've ever done that myself; in some cases I've accessed Imagick or GD directly, but this is definitely cleaner ?

  • Like 4
Link to comment
Share on other sites

@teppo You already got setup by Kixe and Robin. So, only thing that I can contribute is, if you are using this in an environment that allows overwriting existing files with same filename, you should bind a check of last modified timestamps into your program logic:

If fileFieldItem is image and not thumbnail exists: create a thumbnail

If fileFieldItem is image and not thumbnail exists OR if origTimestamp is newer than thumbnailTimestamp: create a (new) thumbnail

  • Like 4
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...