}
$this->type = $type;
- if($this->is_imagick()) {
- $this->image = new Imagick();
- $this->image->readImageBlob($data);
+ if($this->is_imagick() && $this->load_data($data)) {
+ return true;
+ } else {
+ // Failed to load with Imagick, fallback
+ $this->imagick = false;
+ }
+ return $this->load_data($data);
+ }
+
+ public function __destruct() {
+ if($this->image) {
+ if($this->is_imagick()) {
+ $this->image->clear();
+ $this->image->destroy();
+ return;
+ }
+ imagedestroy($this->image);
+ }
+ }
+
+ public function is_imagick() {
+ return $this->imagick;
+ }
+
+ /**
+ * Maps Mime types to Imagick formats
+ */
+ public function get_FormatsMap() {
+ $m = array(
+ 'image/jpeg' => 'JPG',
+ 'image/png' => 'PNG',
+ 'image/gif' => 'GIF'
+ );
+ return $m;
+ }
+
+ private function load_data($data) {
+ if($this->is_imagick()) {
+ $this->image = new Imagick();
+ try {
+ $this->image->readImageBlob($data);
+ }
+ catch (Exception $e) {
+ // Imagick couldn't use the data
+ return false;
+ }
/**
* Setup the image to the format it will be saved to
$quality = JPEG_QUALITY;
$this->image->setCompressionQuality($quality);
}
- } else {
- $this->valid = false;
- $this->image = @imagecreatefromstring($data);
- if($this->image !== FALSE) {
- $this->width = imagesx($this->image);
- $this->height = imagesy($this->image);
- $this->valid = true;
- imagealphablending($this->image, false);
- imagesavealpha($this->image, true);
- }
- }
- }
-
- public function __destruct() {
- if($this->image) {
- if($this->is_imagick()) {
- $this->image->clear();
- $this->image->destroy();
- return;
- }
- imagedestroy($this->image);
- }
- }
-
- public function is_imagick() {
- return $this->imagick;
- }
- /**
- * Maps Mime types to Imagick formats
- */
- public function get_FormatsMap() {
- $m = array(
- 'image/jpeg' => 'JPG',
- 'image/png' => 'PNG',
- 'image/gif' => 'GIF'
- );
- return $m;
- }
+ // The 'width' and 'height' properties are only used by non-Imagick routines.
+ $this->width = $this->image->getImageWidth();
+ $this->height = $this->image->getImageHeight();
+ $this->valid = true;
+
+ return true;
+ }
+
+ $this->valid = false;
+ $this->image = @imagecreatefromstring($data);
+ if($this->image !== FALSE) {
+ $this->width = imagesx($this->image);
+ $this->height = imagesy($this->image);
+ $this->valid = true;
+ imagealphablending($this->image, false);
+ imagesavealpha($this->image, true);
+
+ return true;
+ }
+
+ return false;
+ }
public function is_valid() {
if($this->is_imagick())
if(!$this->is_valid())
return FALSE;
- if($this->is_imagick()) {
- /**
- * If it is not animated, there will be only one iteration here,
- * so don't bother checking
- */
- // Don't forget to go back to the first frame
- $this->image->setFirstIterator();
- do {
- $this->image->resizeImage($max, $max, imagick::FILTER_LANCZOS, 1, true);
- } while ($this->image->nextImage());
- return;
- }
-
- $width = $this->width;
- $height = $this->height;
+ $width = $this->getWidth();
+ $height = $this->getHeight();
$dest_width = $dest_height = 0;
return FALSE;
if($width > $max && $height > $max) {
- if($width > $height) {
+
+ // very tall image (greater than 16:9)
+ // constrain the width - let the height float.
+
+ if((($height * 9) / 16) > $width) {
+ $dest_width = $max;
+ $dest_height = intval(( $height * $max ) / $width);
+ }
+
+ // else constrain both dimensions
+
+ elseif($width > $height) {
$dest_width = $max;
$dest_height = intval(( $height * $max ) / $width);
}
}
else {
if( $height > $max ) {
- $dest_width = intval(( $width * $max ) / $height);
- $dest_height = $max;
+
+ // very tall image (greater than 16:9)
+ // but width is OK - don't do anything
+
+ if((($height * 9) / 16) > $width) {
+ $dest_width = $width;
+ $dest_height = $height;
+ }
+ else {
+ $dest_width = intval(( $width * $max ) / $height);
+ $dest_height = $max;
+ }
}
else {
$dest_width = $width;
}
+ if($this->is_imagick()) {
+ /**
+ * If it is not animated, there will be only one iteration here,
+ * so don't bother checking
+ */
+ // Don't forget to go back to the first frame
+ $this->image->setFirstIterator();
+ do {
+
+ // FIXME - implement horizantal bias for scaling as in followin GD functions
+ // to allow very tall images to be constrained only horizontally.
+
+ $this->image->scaleImage($dest_width, $dest_height);
+ } while ($this->image->nextImage());
+
+ // These may not be necessary any more
+ $this->width = $this->image->getImageWidth();
+ $this->height = $this->image->getImageHeight();
+
+ return;
+ }
+
+
$dest = imagecreatetruecolor( $dest_width, $dest_height );
imagealphablending($dest, false);
imagesavealpha($dest, true);
if(!$this->is_valid())
return FALSE;
- if($this->is_imagick())
- return $this->scaleImage($min);
- $width = $this->width;
- $height = $this->height;
+ $width = $this->getWidth();
+ $height = $this->getHeight();
$dest_width = $dest_height = 0;
}
}
+ if($this->is_imagick())
+ return $this->scaleImage($dest_width,$dest_height);
$dest = imagecreatetruecolor( $dest_width, $dest_height );
imagealphablending($dest, false);
if($this->is_imagick()) {
$this->image->setFirstIterator();
do {
- $this->image->resizeImage($dim, $dim, imagick::FILTER_LANCZOS, 1, false);
+ $this->image->scaleImage($dim, $dim);
} while ($this->image->nextImage());
return;
}
if(!$this->is_valid())
return FALSE;
- if($this->is_imagick()) {
- $this->image->setFirstIterator();
- do {
- $this->image->cropImage($w, $h, $x, $y);
- /**
- * We need to remove the canva,
- * or the image is not resized to the crop:
- * http://php.net/manual/en/imagick.cropimage.php#97232
- */
- $this->image->setImagePage(0, 0, 0, 0);
- } while ($this->image->nextImage());
- return $this->scaleImage($max);
- }
+ if($this->is_imagick()) {
+ $this->image->setFirstIterator();
+ do {
+ $this->image->cropImage($w, $h, $x, $y);
+ /**
+ * We need to remove the canva,
+ * or the image is not resized to the crop:
+ * http://php.net/manual/en/imagick.cropimage.php#97232
+ */
+ $this->image->setImagePage(0, 0, 0, 0);
+ } while ($this->image->nextImage());
+ return $this->scaleImage($max);
+ }
$dest = imagecreatetruecolor( $max, $max );
imagealphablending($dest, false);
`album` = '%s',
`height` = %d,
`width` = %d,
+ `datasize` = %d,
`data` = '%s',
`scale` = %d,
`profile` = %d,
dbesc($album),
intval($this->getHeight()),
intval($this->getWidth()),
+ dbesc(strlen($this->imageString())),
dbesc($this->imageString()),
intval($scale),
intval($profile),
}
else {
$r = q("INSERT INTO `photo`
- ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s' )",
+ ( `uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `datasize`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid` )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s' )",
intval($uid),
intval($cid),
dbesc($guid),
dbesc($album),
intval($this->getHeight()),
intval($this->getWidth()),
+ dbesc(strlen($this->imageString())),
dbesc($this->imageString()),
intval($scale),
intval($profile),
}
if (is_null($type)){
// Guessing from extension? Isn't that... dangerous?
- if(class_exists('Imagick')) {
+ if(class_exists('Imagick') && file_exists($filename) && is_readable($filename)) {
/**
* Well, this not much better,
* but at least it comes from the data inside the image,
intval($uid),
intval($cid)
);
- if(count($r)) {
+ if(count($r) && strlen($r[0]['resource-id'])) {
$hash = $r[0]['resource-id'];
}
else {