Skip to content

Instantly share code, notes, and snippets.

@beije
Last active November 15, 2018 21:32
Show Gist options
  • Save beije/8255877 to your computer and use it in GitHub Desktop.
Save beije/8255877 to your computer and use it in GitHub Desktop.
A small PHP class that can handle the extraction of preview files from a camera RAW file. Dependencies: imagemagick, ufraw and exiv2.

Camera Raw parsing with php

A class that can fetch preview images from camera raw files.

In order to use this class you'll need a few php mods and some other software installed on your server.

  • imagemagick (Manage images)
  • ufraw (Reading and converting raw files)
  • exiv2 (Extracting previews from raw files)

Click here for more information and documentation.

<?php
/**
* A class that can fetch preview images from camera raw files.
*
* In order to use this class you'll need a few php mods and
* some other software installed on your server.
*
* - imagemagick (Manage images)
* - ufraw (Reading and converting raw files)
* - exiv2 (Extracting previews from raw files)
*
*/
class CameraRaw {
/**
* @var array an array containing popular raw file format extensions
*/
private static $rawExtensions = array('.ari','.arw','.bay','.crw','.cr2','.cap','.dcs','.dcr','.dng','.drf','.eip','.erf','.fff','.iiq','.k25','.kdc','.mdc','.mef','.mos','.mrw','.nef','.nrw','.obm','.orf','.pef','.ptx','.pxn','.r3d','.raf','.raw','.rwl','.rw2','.rwz','.sr2','.srf','.srw', '.x3f');
/**
* Checks if a file exists based on the filepath.
*
* @param string $filePath the path to the file
* @return bool returns true if the file exists
*/
private static function checkFile($filePath) {
if(file_exists($filePath)) {
return true;
}
return false;
}
/**
* Checks if a file is a raw file based on file extension.
*
* @param string $filePath the path to the file
* @return bool returns true if the file is a raw type
*/
public static function isRawFile($filePath) {
$fileExtension = '.' . pathinfo($filePath, PATHINFO_EXTENSION);
if(in_array(strToLower($fileExtension), self::$rawExtensions)) {
return true;
}
return false;
}
/**
* Fetches all preview types that are embedded in an image.
*
* @param string $filePath the path to the file
* @return array all the detected previews.
*/
public static function embeddedPreviews($filePath) {
if(!self::checkFile($filePath)) {
throw new \InvalidArgumentException('Incorrect filepath given');
}
$previews = array();
exec('exiv2 -pp "'.$filePath.'"', $previews);
return $previews;
}
/**
* Generates a new jpg image with new sizes from an already existing file.
* (This will also work on raw files, but it will be exceptionally
* slower than extracting the preview).
*
* @param string $sourceFilePath the path to the original file
* @param string $targetFilePath the path to the target file
* @param int $width the max width
* @param int $height the max height of the image
* @param int $quality the quality of the new image (0-100)
*
* @throws \InvalidArgumentException
*
* @return void.
*/
public static function generateImage($sourceFilePath, $targetFilePath, $width, $height, $quality = 60) {
if(!self::checkFile($sourceFilePath)) {
throw new \InvalidArgumentException('Incorrect filepath given');
}
$im = new \Imagick($sourceFilePath);
$im->setImageFormat('jpg');
$im->setImageCompressionQuality($quality);
$im->stripImage();
$im->thumbnailImage($width, $height, true);
$im->writeImage($targetFilePath);
$im->clear();
$im->destroy();
}
/**
* Extracts a preview image from an image and saves the
* image to the designated path.
*
* @param string $sourceFilePath the path to the original file
* @param string $targetFilePath the path to the new file
* @param int $previewNumber which preview (defaults to the highest preview)
*
* @throws \InvalidArgumentException
* @throws \Exception
*
* @return void.
*/
public static function extractPreview($sourceFilePath, $targetFilePath, $previewNumber = null) {
// check that the source file exists.
if(!self::checkFile($sourceFilePath)) {
throw new \InvalidArgumentException('Incorrect source filepath given '.$sourceFilePath);
}
// fetch the all the preview images (and verify that there indeed exit previews)
$numberOfPreviews = self::embeddedPreviews($sourceFilePath);
if(count($numberOfPreviews) == 0) {
throw new \Exception('No embedded previews detected');
}
// default to the last preview
if(is_null($previewNumber)) {
$previewNumber = count($numberOfPreviews);
}
$previewNumber = intval($previewNumber);
$filename = pathinfo($sourceFilePath, PATHINFO_FILENAME);
$return = array();
// generate the preview with exiv2, save it to the temp directory
exec('exiv2 -ep'.$previewNumber.' -l '.sys_get_temp_dir(). ' "' . $sourceFilePath . '"', $return);
$previewFilePath = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $filename . '-preview' . $previewNumber . '.jpg';
// check that the preview got saved correctly
if(!self::checkFile($previewFilePath)) {
throw new \Exception('No preview file.');
}
// copy the preview to the target path and remove the original one in temp
copy($previewFilePath, $targetFilePath);
unlink($previewFilePath);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment