* @link http://status.net/
*/
-if (!defined('STATUSNET') && !defined('LACONICA')) {
- exit(1);
-}
+if (!defined('GNUSOCIAL')) { exit(1); }
/**
* A wrapper on uploaded files
($info[2] == IMAGETYPE_XBM && function_exists('imagecreatefromxbm')) ||
($info[2] == IMAGETYPE_PNG && function_exists('imagecreatefrompng')))) {
- throw new Exception(_('Unsupported image file format.'));
- return;
+ // TRANS: Exception thrown when trying to upload an unsupported image file format.
+ throw new UnsupportedMediaException(_('Unsupported image format.'), $this->filepath);
}
$this->type = ($info) ? $info[2]:$type;
$this->height = ($info) ? $info[1]:$height;
}
+ public function getPath()
+ {
+ if (!file_exists($this->filepath)) {
+ throw new ServerException('No file in ImageFile filepath');
+ }
+
+ return $this->filepath;
+ }
+
static function fromUpload($param='upload')
{
switch ($_FILES[$param]['error']) {
case UPLOAD_ERR_OK: // success, jump out
break;
+
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
// TRANS: Exception thrown when too large a file is uploaded.
// TRANS: %s is the maximum file size, for example "500b", "10kB" or "2MB".
- throw new Exception(sprintf(_('That file is too big. The maximum file size is %s.'),
- ImageFile::maxFileSize()));
- return;
+ throw new Exception(sprintf(_('That file is too big. The maximum file size is %s.'), ImageFile::maxFileSize()));
+
case UPLOAD_ERR_PARTIAL:
@unlink($_FILES[$param]['tmp_name']);
+ // TRANS: Exception thrown when uploading an image and that action could not be completed.
throw new Exception(_('Partial upload.'));
- return;
+
case UPLOAD_ERR_NO_FILE:
// No file; probably just a non-AJAX submission.
- return;
default:
- common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " .
- $_FILES[$param]['error']);
+ common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " . $_FILES[$param]['error']);
+ // TRANS: Exception thrown when uploading an image fails for an unknown reason.
throw new Exception(_('System error uploading file.'));
- return;
}
$info = @getimagesize($_FILES[$param]['tmp_name']);
if (!$info) {
@unlink($_FILES[$param]['tmp_name']);
- throw new Exception(_('Not an image or corrupt file.'));
- return;
+ // TRANS: Exception thrown when uploading a file as image that is not an image or is a corrupt file.
+ throw new UnsupportedMediaException(_('Not an image or corrupt file.'), '[deleted]');
}
return new ImageFile(null, $_FILES[$param]['tmp_name']);
*/
function resize($size, $x = 0, $y = 0, $w = null, $h = null)
{
- $targetType = $this->preferredType($this->type);
+ $targetType = $this->preferredType();
$outname = Avatar::filename($this->id,
image_type_to_extension($targetType),
$size,
return $outname;
}
+ /**
+ * Copy the image file to the given destination.
+ * For obscure formats, this will automatically convert to PNG;
+ * otherwise the original file will be copied as-is.
+ *
+ * @param string $outpath
+ * @return string filename
+ */
+ function copyTo($outpath)
+ {
+ return $this->resizeTo($outpath, $this->width, $this->height);
+ }
+
/**
* Create and save a thumbnail image.
*
{
$w = ($w === null) ? $this->width:$w;
$h = ($h === null) ? $this->height:$h;
- $targetType = $this->preferredType($this->type);
+ $targetType = $this->preferredType();
if (!file_exists($this->filepath)) {
+ // TRANS: Exception thrown during resize when image has been registered as present, but is no longer there.
throw new Exception(_('Lost our file.'));
- return;
}
// Don't crop/scale if it isn't necessary
$image_src = imagecreatefromxbm($this->filepath);
break;
default:
+ // TRANS: Exception thrown when trying to resize an unknown file type.
throw new Exception(_('Unknown file type'));
- return;
}
$image_dest = imagecreatetruecolor($width, $height);
imagegif($image_dest, $outpath);
break;
case IMAGETYPE_JPEG:
- imagejpeg($image_dest, $outpath, 100);
+ imagejpeg($image_dest, $outpath, common_config('image', 'jpegquality'));
break;
case IMAGETYPE_PNG:
imagepng($image_dest, $outpath);
break;
default:
+ // TRANS: Exception thrown when trying resize an unknown file type.
throw new Exception(_('Unknown file type'));
- return;
}
imagedestroy($image_src);
/**
* Several obscure file types should be normalized to PNG on resize.
*
- * @param int $type
+ * @fixme consider flattening anything not GIF or JPEG to PNG
* @return int
*/
- function preferredType($type)
+ function preferredType()
{
- if($type == IMAGETYPE_BMP) {
+ if($this->type == IMAGETYPE_BMP) {
//we don't want to save BMP... it's an inefficient, rare, antiquated format
//save png instead
return IMAGETYPE_PNG;
- } else if($type == IMAGETYPE_WBMP) {
+ } else if($this->type == IMAGETYPE_WBMP) {
//we don't want to save WBMP... it's a rare format that we can't guarantee clients will support
//save png instead
return IMAGETYPE_PNG;
- } else if($type == IMAGETYPE_XBM) {
+ } else if($this->type == IMAGETYPE_XBM) {
//we don't want to save XBM... it's a rare format that we can't guarantee clients will support
//save png instead
return IMAGETYPE_PNG;
}
- return $type;
+ return $this->type;
}
function unlink()
{
- @unlink($this->filename);
+ @unlink($this->filepath);
}
static function maxFileSize()
return $num;
}
+
+ public function scaleToFit($maxWidth=null, $maxHeight=null, $crop=null)
+ {
+ return self::getScalingValues($this->width, $this->height,
+ $maxWidth, $maxHeight, $crop);
+ }
+
+ /*
+ * Gets scaling values for images of various types. Cropping can be enabled.
+ *
+ * Values will scale _up_ to fit max values if cropping is enabled!
+ * With cropping disabled, the max value of each axis will be respected.
+ *
+ * @param $width int Original width
+ * @param $height int Original height
+ * @param $maxW int Resulting max width
+ * @param $maxH int Resulting max height
+ * @param $crop int Crop to the size (not preserving aspect ratio)
+ */
+ public static function getScalingValues($width, $height,
+ $maxW=null, $maxH=null,
+ $crop=null)
+ {
+ $maxW = $maxW ?: common_config('thumbnail', 'width');
+ $maxH = $maxH ?: common_config('thumbnail', 'height');
+
+ if ($maxW < 1 || ($maxH !== null && $maxH < 1)) {
+ throw new ServerException('Bad parameters for ImageFile::getScalingValues');
+ } elseif ($maxH === null) {
+ // if maxH is null, we set maxH to equal maxW and enable crop
+ $maxH = $maxW;
+ $crop = true;
+ }
+
+ // Cropping data (for original image size). Default values, 0 and null,
+ // imply no cropping and with preserved aspect ratio (per axis).
+ $cx = 0; // crop x
+ $cy = 0; // crop y
+ $cw = null; // crop area width
+ $ch = null; // crop area height
+
+ if ($crop) {
+ $s_ar = $width / $height;
+ $t_ar = $maxW / $maxH;
+
+ $rw = $maxW;
+ $rh = $maxH;
+
+ // Source aspect ratio differs from target, recalculate crop points!
+ if ($s_ar > $t_ar) {
+ $cx = floor($width / 2 - $height * $t_ar / 2);
+ $cw = ceil($height * $t_ar);
+ } elseif ($s_ar < $t_ar) {
+ $cy = floor($height / 2 - $width / $t_ar / 2);
+ $ch = ceil($width / $t_ar);
+ }
+ } else {
+ $rw = $maxW;
+ $rh = ceil($height * $rw / $width);
+
+ // Scaling caused too large height, decrease to max accepted value
+ if ($rh > $maxH) {
+ $rh = $maxH;
+ $rw = ceil($width * $rh / $height);
+ }
+ }
+ return array(intval($rw), intval($rh),
+ intval($cx), intval($cy),
+ is_null($cw) ? null : intval($cw),
+ is_null($ch) ? null : intval($ch));
+ }
}
//PHP doesn't (as of 2/24/2010) have an imagecreatefrombmp so conditionally define one
// Return image-object
return $image;
}
-}
+} // if(!function_exists('imagecreatefrombmp'))