@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve image thumbnailing and increase the size of Macro thumbnails

Summary:
Alternate proposal for D3635.

- Works better with small images.
- Produces a predictable thumbnail size.
- Somewhat reasonable output on 3000x10 images.
- Increase the size of Macro thumbnails to 240px.

Test Plan: {F20497}

Reviewers: vrana, chad

Reviewed By: vrana

CC: aran

Differential Revision: https://secure.phabricator.com/D3638

+81 -28
+52 -9
src/applications/files/PhabricatorImageTransformer.php
··· 47 47 )); 48 48 } 49 49 50 + public function executePreviewTransform( 51 + PhabricatorFile $file, 52 + $size) { 53 + 54 + $image = $this->generatePreview($file, $size); 55 + 56 + return PhabricatorFile::newFromFileData( 57 + $image, 58 + array( 59 + 'name' => 'preview-'.$file->getName(), 60 + )); 61 + } 62 + 63 + 50 64 private function crudelyCropTo(PhabricatorFile $file, $x, $min_y, $max_y) { 51 65 $data = $file->loadFileData(); 52 66 $img = imagecreatefromstring($data); ··· 86 100 $x = imagesx($src); 87 101 $y = imagesy($src); 88 102 89 - $scale = min($x / $dx, $y / $dy); 103 + $scale = min(($dx / $x), ($dy / $y), 1); 104 + 90 105 $dst = imagecreatetruecolor($dx, $dy); 91 106 imagesavealpha($dst, true); 92 - imagefill($dst, 0, 0, imagecolorallocatealpha($dst, 0, 0, 0, 127)); 107 + imagefill($dst, 0, 0, imagecolorallocatealpha($dst, 255, 255, 255, 127)); 93 108 94 - // If we need to chop off some pixels, chop them off from the sides instead 95 - // of scaling in on <0, 0>. 96 - $sdx = $scale * $dx; 97 - $sdy = $scale * $dy; 109 + $sdx = $scale * $x; 110 + $sdy = $scale * $y; 98 111 99 112 imagecopyresampled( 100 113 $dst, 101 114 $src, 115 + ($dx - $sdx) / 2, ($dy - $sdy) / 2, 102 116 0, 0, 103 - ($x - $sdx) / 2, ($y - $sdy) / 2, 104 - $dx, $dy, 105 - $sdx, $sdy); 117 + $sdx, $sdy, 118 + $x, $y); 106 119 107 120 return $dst; 121 + } 122 + 123 + private function generatePreview(PhabricatorFile $file, $size) { 124 + $data = $file->loadFileData(); 125 + $src = imagecreatefromstring($data); 126 + 127 + $x = imagesx($src); 128 + $y = imagesy($src); 129 + 130 + $scale = min($size / $x, $size / $y, 1); 131 + 132 + $dx = max($size / 4, $scale * $x); 133 + $dy = max($size / 4, $scale * $y); 134 + 135 + $dst = imagecreatetruecolor($dx, $dy); 136 + imagesavealpha($dst, true); 137 + imagefill($dst, 0, 0, imagecolorallocatealpha($dst, 255, 255, 255, 127)); 138 + 139 + $sdx = $scale * $x; 140 + $sdy = $scale * $y; 141 + 142 + imagecopyresampled( 143 + $dst, 144 + $src, 145 + ($dx - $sdx) / 2, ($dy - $sdy) / 2, 146 + 0, 0, 147 + $sdx, $sdy, 148 + $x, $y); 149 + 150 + return $this->saveImageDataInAnyFormat($dst, $file->getMimeType()); 108 151 } 109 152 110 153 private function saveImageDataInAnyFormat($data, $preferred_mime = '') {
+11
src/applications/files/controller/PhabricatorFileTransformController.php
··· 55 55 $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); 56 56 57 57 switch ($this->transform) { 58 + case 'thumb-220x165': 59 + $xformed_file = $this->executeThumbTransform($file, 220, 165); 60 + break; 61 + case 'preview-220': 62 + $xformed_file = $this->executePreviewTransform($file, 220); 63 + break; 58 64 case 'thumb-160x120': 59 65 $xformed_file = $this->executeThumbTransform($file, 160, 120); 60 66 break; ··· 131 137 // TODO: We could just delegate to the file view controller instead, 132 138 // which would save the client a roundtrip, but is slightly more complex. 133 139 return id(new AphrontRedirectResponse())->setURI($uri); 140 + } 141 + 142 + private function executePreviewTransform(PhabricatorFile $file, $size) { 143 + $xformer = new PhabricatorImageTransformer(); 144 + return $xformer->executePreviewTransform($file, $size); 134 145 } 135 146 136 147 private function executeThumbTransform(PhabricatorFile $file, $x, $y) {
+7
src/applications/files/storage/PhabricatorFile.php
··· 315 315 return '/file/xform/thumb-160x120/'.$this->getPHID().'/'; 316 316 } 317 317 318 + public function getPreview220URI() { 319 + return '/file/xform/preview-220/'.$this->getPHID().'/'; 320 + } 321 + 322 + public function getThumb220x165URI() { 323 + return '/file/xform/thumb-220x165/'.$this->getPHID().'/'; 324 + } 318 325 319 326 public function isViewableInBrowser() { 320 327 return ($this->getViewableMimeType() !== null);
+2 -3
src/applications/macro/controller/PhabricatorMacroListController.php
··· 99 99 100 100 $item = new PhabricatorPinboardItemView(); 101 101 if ($file) { 102 - $item->setImageURI($file->getThumb160x120URI()); 103 - $item->setImageSize(160, 120); 102 + $item->setImageURI($file->getThumb220x165URI()); 103 + $item->setImageSize(220, 165); 104 104 if ($file->getAuthorPHID()) { 105 105 $author_handle = $this->getHandle($file->getAuthorPHID()); 106 106 $item->appendChild( ··· 112 112 'div', 113 113 array(), 114 114 'Created on '.$datetime)); 115 - 116 115 } 117 116 $item->setURI($this->getApplicationURI('/edit/'.$macro->getID().'/')); 118 117 $item->setHeader($macro->getName());
+5 -8
src/infrastructure/markup/rule/PhabricatorRemarkupRuleEmbedFile.php
··· 68 68 return $this->getEngine()->storeText($link); 69 69 } 70 70 71 - $attrs = array( 72 - 'class' => 'phabricator-remarkup-embed-image', 73 - ); 71 + $attrs = array(); 74 72 75 73 switch ($options['size']) { 76 74 case 'full': ··· 79 77 break; 80 78 case 'thumb': 81 79 default: 82 - $attrs['src'] = $file->getThumb160x120URI(); 83 - $attrs['width'] = 160; 84 - $attrs['height'] = 120; 80 + $attrs['src'] = $file->getPreview220URI(); 85 81 $link = $file->getBestURI(); 86 82 break; 87 83 } ··· 92 88 $embed = phutil_render_tag( 93 89 'a', 94 90 array( 95 - 'href' => $link, 96 - 'target' => '_blank', 91 + 'href' => $link, 92 + 'class' => 'phabricator-remarkup-embed-image', 93 + 'target' => '_blank', 97 94 ), 98 95 $embed); 99 96 }
+4 -8
webroot/rsrc/css/core/remarkup.css
··· 219 219 margin: .5em 1em 0; 220 220 } 221 221 222 - img.phabricator-remarkup-embed-image { 223 - display: inline; 224 - border: 2px solid white; 225 - background: white; 226 - 227 - box-shadow: 1px 1px 6px rgba(0,0,0,.5); 228 - -moz-box-shadow: 1px 1px 6px rgba(0,0,0,.5); 229 - -webkit-box-shadow: 1px 1px 6px rgba(0,0,0,.5); 222 + .phabricator-remarkup-embed-image { 223 + display: inline-block; 224 + border: 3px solid white; 225 + box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.20); 230 226 } 231 227 232 228 .phabricator-remarkup table.remarkup-table {