mirror of
https://we.phorge.it/source/phorge.git
synced 2025-03-25 10:40:16 +01:00
Convert "preview" image transforms to new pathway
Summary: Ref T7707. Move the 220px (file uploads) and 100px (Pholio thumbgrid) previews over to the new stuff. Test Plan: Uploaded a bunch of images to remarkup and Pholio; they generated reasonable results in the web UI. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T7707 Differential Revision: https://secure.phabricator.com/D12814
This commit is contained in:
parent
200e525df1
commit
75f6211233
12 changed files with 118 additions and 121 deletions
|
@ -51,20 +51,6 @@ final class PhabricatorImageTransformer {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function executePreviewTransform(
|
|
||||||
PhabricatorFile $file,
|
|
||||||
$size) {
|
|
||||||
|
|
||||||
$image = $this->generatePreview($file, $size);
|
|
||||||
|
|
||||||
return PhabricatorFile::newFromFileData(
|
|
||||||
$image,
|
|
||||||
array(
|
|
||||||
'name' => 'preview-'.$file->getName(),
|
|
||||||
'canCDN' => true,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function executeConpherenceTransform(
|
public function executeConpherenceTransform(
|
||||||
PhabricatorFile $file,
|
PhabricatorFile $file,
|
||||||
$top,
|
$top,
|
||||||
|
@ -188,37 +174,6 @@ final class PhabricatorImageTransformer {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getPreviewDimensions(PhabricatorFile $file, $size) {
|
|
||||||
$metadata = $file->getMetadata();
|
|
||||||
$x = idx($metadata, PhabricatorFile::METADATA_IMAGE_WIDTH);
|
|
||||||
$y = idx($metadata, PhabricatorFile::METADATA_IMAGE_HEIGHT);
|
|
||||||
|
|
||||||
if (!$x || !$y) {
|
|
||||||
$data = $file->loadFileData();
|
|
||||||
$src = imagecreatefromstring($data);
|
|
||||||
|
|
||||||
$x = imagesx($src);
|
|
||||||
$y = imagesy($src);
|
|
||||||
}
|
|
||||||
|
|
||||||
$scale = min($size / $x, $size / $y, 1);
|
|
||||||
|
|
||||||
$dx = max($size / 4, $scale * $x);
|
|
||||||
$dy = max($size / 4, $scale * $y);
|
|
||||||
|
|
||||||
$sdx = $scale * $x;
|
|
||||||
$sdy = $scale * $y;
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'x' => $x,
|
|
||||||
'y' => $y,
|
|
||||||
'dx' => $dx,
|
|
||||||
'dy' => $dy,
|
|
||||||
'sdx' => $sdx,
|
|
||||||
'sdy' => $sdy,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getScaleForCrop(
|
public static function getScaleForCrop(
|
||||||
PhabricatorFile $file,
|
PhabricatorFile $file,
|
||||||
$des_width,
|
$des_width,
|
||||||
|
@ -241,31 +196,6 @@ final class PhabricatorImageTransformer {
|
||||||
return $scale;
|
return $scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function generatePreview(PhabricatorFile $file, $size) {
|
|
||||||
$data = $file->loadFileData();
|
|
||||||
$src = imagecreatefromstring($data);
|
|
||||||
|
|
||||||
$dimensions = self::getPreviewDimensions($file, $size);
|
|
||||||
$x = $dimensions['x'];
|
|
||||||
$y = $dimensions['y'];
|
|
||||||
$dx = $dimensions['dx'];
|
|
||||||
$dy = $dimensions['dy'];
|
|
||||||
$sdx = $dimensions['sdx'];
|
|
||||||
$sdy = $dimensions['sdy'];
|
|
||||||
|
|
||||||
$dst = $this->getBlankDestinationFile($dx, $dy);
|
|
||||||
|
|
||||||
imagecopyresampled(
|
|
||||||
$dst,
|
|
||||||
$src,
|
|
||||||
($dx - $sdx) / 2, ($dy - $sdy) / 2,
|
|
||||||
0, 0,
|
|
||||||
$sdx, $sdy,
|
|
||||||
$x, $y);
|
|
||||||
|
|
||||||
return self::saveImageDataInAnyFormat($dst, $file->getMimeType());
|
|
||||||
}
|
|
||||||
|
|
||||||
private function applyMemeToFile(
|
private function applyMemeToFile(
|
||||||
PhabricatorFile $file,
|
PhabricatorFile $file,
|
||||||
$upper_text,
|
$upper_text,
|
||||||
|
|
|
@ -85,12 +85,6 @@ final class PhabricatorFileTransformController
|
||||||
case 'thumb-280x210':
|
case 'thumb-280x210':
|
||||||
$xformed_file = $this->executeThumbTransform($file, 280, 210);
|
$xformed_file = $this->executeThumbTransform($file, 280, 210);
|
||||||
break;
|
break;
|
||||||
case 'preview-100':
|
|
||||||
$xformed_file = $this->executePreviewTransform($file, 100);
|
|
||||||
break;
|
|
||||||
case 'preview-220':
|
|
||||||
$xformed_file = $this->executePreviewTransform($file, 220);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
return new Aphront400Response();
|
return new Aphront400Response();
|
||||||
}
|
}
|
||||||
|
@ -132,9 +126,6 @@ final class PhabricatorFileTransformController
|
||||||
case 'thumb-280x210':
|
case 'thumb-280x210':
|
||||||
$suffix = '280x210';
|
$suffix = '280x210';
|
||||||
break;
|
break;
|
||||||
case 'preview-100':
|
|
||||||
$suffix = '.p100';
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new Exception('Unsupported transformation type!');
|
throw new Exception('Unsupported transformation type!');
|
||||||
}
|
}
|
||||||
|
@ -163,11 +154,6 @@ final class PhabricatorFileTransformController
|
||||||
return $file->getRedirectResponse();
|
return $file->getRedirectResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function executePreviewTransform(PhabricatorFile $file, $size) {
|
|
||||||
$xformer = new PhabricatorImageTransformer();
|
|
||||||
return $xformer->executePreviewTransform($file, $size);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function executeThumbTransform(PhabricatorFile $file, $x, $y) {
|
private function executeThumbTransform(PhabricatorFile $file, $x, $y) {
|
||||||
$xformer = new PhabricatorImageTransformer();
|
$xformer = new PhabricatorImageTransformer();
|
||||||
return $xformer->executeThumbTransform($file, $x, $y);
|
return $xformer->executeThumbTransform($file, $x, $y);
|
||||||
|
|
|
@ -107,11 +107,17 @@ final class PhabricatorEmbedFileRemarkupRule
|
||||||
break;
|
break;
|
||||||
case 'thumb':
|
case 'thumb':
|
||||||
default:
|
default:
|
||||||
$attrs['src'] = $file->getPreview220URI();
|
$preview_key = PhabricatorFileThumbnailTransform::TRANSFORM_PREVIEW;
|
||||||
$dimensions =
|
$xform = PhabricatorFileTransform::getTransformByKey($preview_key);
|
||||||
PhabricatorImageTransformer::getPreviewDimensions($file, 220);
|
$attrs['src'] = $file->getURIForTransform($xform);
|
||||||
$attrs['width'] = $dimensions['dx'];
|
|
||||||
$attrs['height'] = $dimensions['dy'];
|
$dimensions = $xform->getTransformedDimensions($file);
|
||||||
|
if ($dimensions) {
|
||||||
|
list($x, $y) = $dimensions;
|
||||||
|
$attrs['width'] = $x;
|
||||||
|
$attrs['height'] = $y;
|
||||||
|
}
|
||||||
|
|
||||||
$image_class = 'phabricator-remarkup-embed-image';
|
$image_class = 'phabricator-remarkup-embed-image';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -788,14 +788,6 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
||||||
return $this->getTransformedURI('thumb-profile');
|
return $this->getTransformedURI('thumb-profile');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPreview100URI() {
|
|
||||||
return $this->getTransformedURI('preview-100');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPreview220URI() {
|
|
||||||
return $this->getTransformedURI('preview-220');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getThumb280x210URI() {
|
public function getThumb280x210URI() {
|
||||||
return $this->getTransformedURI('thumb-280x210');
|
return $this->getTransformedURI('thumb-280x210');
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,16 @@ abstract class PhabricatorFileImageTransform extends PhabricatorFileTransform {
|
||||||
private $imageX;
|
private $imageX;
|
||||||
private $imageY;
|
private $imageY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an estimate of the transformed dimensions of a file.
|
||||||
|
*
|
||||||
|
* @param PhabricatorFile File to transform.
|
||||||
|
* @return list<int, int>|null Width and height, if available.
|
||||||
|
*/
|
||||||
|
public function getTransformedDimensions(PhabricatorFile $file) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function canApplyTransform(PhabricatorFile $file) {
|
public function canApplyTransform(PhabricatorFile $file) {
|
||||||
if (!$file->isViewableImage()) {
|
if (!$file->isViewableImage()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -65,6 +65,59 @@ final class PhabricatorFileThumbnailTransform
|
||||||
$dst_x = $this->dstX;
|
$dst_x = $this->dstX;
|
||||||
$dst_y = $this->dstY;
|
$dst_y = $this->dstY;
|
||||||
|
|
||||||
|
$dimensions = $this->computeDimensions(
|
||||||
|
$src_x,
|
||||||
|
$src_y,
|
||||||
|
$dst_x,
|
||||||
|
$dst_y);
|
||||||
|
|
||||||
|
$copy_x = $dimensions['copy_x'];
|
||||||
|
$copy_y = $dimensions['copy_y'];
|
||||||
|
$use_x = $dimensions['use_x'];
|
||||||
|
$use_y = $dimensions['use_y'];
|
||||||
|
$dst_x = $dimensions['dst_x'];
|
||||||
|
$dst_y = $dimensions['dst_y'];
|
||||||
|
|
||||||
|
return $this->applyCropAndScale(
|
||||||
|
$dst_x,
|
||||||
|
$dst_y,
|
||||||
|
($src_x - $copy_x) / 2,
|
||||||
|
($src_y - $copy_y) / 2,
|
||||||
|
$copy_x,
|
||||||
|
$copy_y,
|
||||||
|
$use_x,
|
||||||
|
$use_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getTransformedDimensions(PhabricatorFile $file) {
|
||||||
|
$dst_x = $this->dstX;
|
||||||
|
$dst_y = $this->dstY;
|
||||||
|
|
||||||
|
// If this is transform has fixed dimensions, we can trivially predict
|
||||||
|
// the dimensions of the transformed file.
|
||||||
|
if ($dst_y !== null) {
|
||||||
|
return array($dst_x, $dst_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
$src_x = $file->getImageWidth();
|
||||||
|
$src_y = $file->getImageHeight();
|
||||||
|
|
||||||
|
if (!$src_x || !$src_y) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dimensions = $this->computeDimensions(
|
||||||
|
$src_x,
|
||||||
|
$src_y,
|
||||||
|
$dst_x,
|
||||||
|
$dst_y);
|
||||||
|
|
||||||
|
return array($dimensions['dst_x'], $dimensions['dst_y']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function computeDimensions($src_x, $src_y, $dst_x, $dst_y) {
|
||||||
if ($dst_y === null) {
|
if ($dst_y === null) {
|
||||||
// If we only have one dimension, it represents a maximum dimension.
|
// If we only have one dimension, it represents a maximum dimension.
|
||||||
// The other dimension of the transform is scaled appropriately, except
|
// The other dimension of the transform is scaled appropriately, except
|
||||||
|
@ -115,17 +168,17 @@ final class PhabricatorFileThumbnailTransform
|
||||||
$use_y = $dst_y;
|
$use_y = $dst_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->applyCropAndScale(
|
return array(
|
||||||
$dst_x,
|
'copy_x' => $copy_x,
|
||||||
$dst_y,
|
'copy_y' => $copy_y,
|
||||||
($src_x - $copy_x) / 2,
|
'use_x' => $use_x,
|
||||||
($src_y - $copy_y) / 2,
|
'use_y' => $use_y,
|
||||||
$copy_x,
|
'dst_x' => $dst_x,
|
||||||
$copy_y,
|
'dst_y' => $dst_y,
|
||||||
$use_x,
|
);
|
||||||
$use_y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getDefaultTransform(PhabricatorFile $file) {
|
public function getDefaultTransform(PhabricatorFile $file) {
|
||||||
$x = (int)$this->dstX;
|
$x = (int)$this->dstX;
|
||||||
$y = (int)$this->dstY;
|
$y = (int)$this->dstY;
|
||||||
|
|
|
@ -45,4 +45,18 @@ abstract class PhabricatorFileTransform extends Phobject {
|
||||||
return $map;
|
return $map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getTransformByKey($key) {
|
||||||
|
$all = self::getAllTransforms();
|
||||||
|
|
||||||
|
$xform = idx($all, $key);
|
||||||
|
if (!$xform) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'No file transform with key "%s" exists.',
|
||||||
|
$key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $xform;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,28 +114,34 @@ final class PholioMockThumbGridView extends AphrontView {
|
||||||
private function renderThumbnail(PholioImage $image) {
|
private function renderThumbnail(PholioImage $image) {
|
||||||
$thumbfile = $image->getFile();
|
$thumbfile = $image->getFile();
|
||||||
|
|
||||||
|
$preview_key = PhabricatorFileThumbnailTransform::TRANSFORM_THUMBGRID;
|
||||||
|
$xform = PhabricatorFileTransform::getTransformByKey($preview_key);
|
||||||
|
|
||||||
|
$attributes = array(
|
||||||
|
'class' => 'pholio-mock-thumb-grid-image',
|
||||||
|
'src' => $thumbfile->getURIForTransform($xform),
|
||||||
|
);
|
||||||
|
|
||||||
if ($image->getFile()->isViewableImage()) {
|
if ($image->getFile()->isViewableImage()) {
|
||||||
$dimensions = PhabricatorImageTransformer::getPreviewDimensions(
|
$dimensions = $xform->getTransformedDimensions($thumbfile);
|
||||||
$thumbfile,
|
if ($dimensions) {
|
||||||
100);
|
list($x, $y) = $dimensions;
|
||||||
|
$attributes += array(
|
||||||
|
'width' => $x,
|
||||||
|
'height' => $y,
|
||||||
|
'style' => 'top: '.floor((100 - $y) / 2).'px',
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// If this is a PDF or a text file or something, we'll end up using a
|
// If this is a PDF or a text file or something, we'll end up using a
|
||||||
// generic thumbnail which is always sized correctly.
|
// generic thumbnail which is always sized correctly.
|
||||||
$dimensions = array(
|
$attributes += array(
|
||||||
'sdx' => 100,
|
'width' => 100,
|
||||||
'sdy' => 100,
|
'height' => 100,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag = phutil_tag(
|
$tag = phutil_tag('img', $attributes);
|
||||||
'img',
|
|
||||||
array(
|
|
||||||
'width' => $dimensions['sdx'],
|
|
||||||
'height' => $dimensions['sdy'],
|
|
||||||
'src' => $thumbfile->getPreview100URI(),
|
|
||||||
'class' => 'pholio-mock-thumb-grid-image',
|
|
||||||
'style' => 'top: '.floor((100 - $dimensions['sdy'] ) / 2).'px',
|
|
||||||
));
|
|
||||||
|
|
||||||
$classes = array('pholio-mock-thumb-grid-item');
|
$classes = array('pholio-mock-thumb-grid-item');
|
||||||
if ($image->getIsObsolete()) {
|
if ($image->getIsObsolete()) {
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2 KiB |
Loading…
Add table
Reference in a new issue