diff --git a/apps/gallery/ajax/thumbnail.php b/apps/gallery/ajax/thumbnail.php
index ff0cb44022c..4fc9eba992d 100644
--- a/apps/gallery/ajax/thumbnail.php
+++ b/apps/gallery/ajax/thumbnail.php
@@ -20,14 +20,15 @@
* License along with this library. If not, see .
*
*/
-
OCP\JSON::checkLoggedIn();
OCP\JSON::checkAppEnabled('gallery');
+require_once('apps/gallery/lib/managers.php');
-$img = $_GET['img'];
-$image = OC_Gallery_Photo::getThumbnail($img);
+$img = $_GET['filepath'];
+
+$image = \OC\Pictures\ThumbnailsManager::getInstance()->getThumbnail($img);
if ($image) {
OCP\Response::enableCaching(3600 * 24); // 24 hour
$image->show();
diff --git a/apps/gallery/lib/managers.php b/apps/gallery/lib/managers.php
new file mode 100644
index 00000000000..96669da2727
--- /dev/null
+++ b/apps/gallery/lib/managers.php
@@ -0,0 +1,94 @@
+execute(array(\OCP\USER::getUser(), $path));
+ if (($row = $result->fetchRow()) != false) {
+ return $row;
+ }
+ $image = new \OC_Image();
+ if (!$image->loadFromFile($path)) {
+ return false;
+ }
+ $stmt = \OCP\DB::prepare('INSERT INTO *PREFIX*pictures_images_cache (uid_owner, path, width, height) VALUES (?, ?, ?, ?)');
+ $stmt->execute(array(\OCP\USER::getUser(), $path, $image->width(), $image->height()));
+ unset($image);
+ return $this->getFileData($path);
+ }
+
+ private function __construct() {}
+}
+
+class ThumbnailsManager {
+
+ private static $instance = null;
+ const TAG = 'ThumbnailManager';
+
+ public static function getInstance() {
+ if (self::$instance === null)
+ self::$instance = new ThumbnailsManager();
+ return self::$instance;
+ }
+
+ public function getThumbnail($path) {
+ $gallery_path = \OCP\Config::getSystemValue( 'datadirectory' ).'/'.\OC_User::getUser().'/gallery';
+ if (file_exists($gallery_path.$path)) {
+ return new \OC_Image($gallery_path.$path);
+ }
+ if (!\OC_Filesystem::file_exists($path)) {
+ \OC_Log::write(self::TAG, 'File '.$path.' don\'t exists', \OC_Log::WARN);
+ return false;
+ }
+ $image = new \OC_Image();
+ $image->loadFromFile(\OC_Filesystem::getLocalFile($path));
+ if (!$image->valid()) return false;
+
+ $image->fixOrientation();
+
+ $ret = $image->preciseResize(floor((200*$image->width())/$image->height()), 200);
+
+ if (!$ret) {
+ \OC_Log::write(self::TAG, 'Couldn\'t resize image', \OC_Log::ERROR);
+ unset($image);
+ return false;
+ }
+
+ $image->save($gallery_path.'/'.$path);
+ return $image;
+ }
+
+ public function getThumbnailInfo($path) {
+ $arr = DatabaseManager::getInstance()->getFileData($path);
+ $ret = array('filepath' => $arr['path'],
+ 'width' => $arr['width'],
+ 'height' => $arr['height']);
+ return $ret;
+ }
+
+ public function delete($path) {
+ unlink(\OC::$CONFIG_DATADIRECTORY_ROOT.'/'.\OC_User::getUser()."/gallery".$path);
+ }
+
+ private function __construct() {}
+
+}
+?>
\ No newline at end of file
diff --git a/apps/gallery/lib/testimg.jpg b/apps/gallery/lib/testimg.jpg
new file mode 100644
index 00000000000..0d9a2bd8812
Binary files /dev/null and b/apps/gallery/lib/testimg.jpg differ
diff --git a/apps/gallery/lib/tiles.php b/apps/gallery/lib/tiles.php
new file mode 100644
index 00000000000..d7f5208ff83
--- /dev/null
+++ b/apps/gallery/lib/tiles.php
@@ -0,0 +1,183 @@
+tiles_array = array();
+ }
+
+ public function setAvailableSpace($space) {
+ $available_space = $space;
+ }
+
+ public function getTilesCount() {
+ return count($this->tiles_array);
+ }
+
+ public function addTile($tile) {
+ array_push($this->tiles_array, $tile);
+ }
+
+ public function getLeftSpace() {
+ $occupied_space = 0;
+ for ($i = 0; $i < count($this->tiles_array); $i++) {
+ $occupied_space += $this->tiles_array[$i]->getWidth();
+ }
+ return $this->available_space - $occupied_space;
+ }
+
+ public function tileWillFit($tile) {
+ return $this->getLeftSpace() > $tile->getWidth();
+ }
+
+ public function get() {
+ $r = '
';
+
+ for ($i = 0; $i < count($this->tiles_array); $i++) {
+ $img_w = $this->tiles_array[$i]->getWidth();
+ $extra = '';
+ if ($img_w != 200) $extra = ' style="width:'.$img_w.'px"';
+ $r .= '
'.$this->tiles_array[$i]->get().'
';
+ }
+
+ $r .= '
';
+ return $r;
+ }
+
+ private $tiles_array;
+ private $available_space;
+}
+
+class TileSingle extends TileBase {
+
+ public function __construct($path) {
+ \OC_Log::write(TAG, 'Loading file from path '.$path, \OC_Log::DEBUG);
+ $this->file_path = $path;
+/* $this->image = new \OC_Image();
+ if (!$this->image->loadFromFile($this->file_path)) {
+ \OC_Log::write(TAG, 'Loading file filed', \OC_Log::ERROR);
+ return;
+ }
+ $this->image->fixOrientation();*/
+ }
+
+ public function getWidth() {
+ $a = ThumbnailsManager::getInstance()->getThumbnailInfo($this->file_path);
+ return $a['width'];
+ }
+
+ public function forceSize($width_must_fit=false) {
+ $current_height = $this->image->height();
+ $current_width = $this->image->width();
+
+ // we need height of 250px but not for tiles stack
+ if ($current_width > $current_height && !$width_must_fit) {
+ $this->image->resize(floor((250*$current_width)/$current_height));
+ } else {
+ $this->image->resize(200);
+ }
+ }
+
+ public function get($extra = '') {
+ return '
';
+ }
+
+ public function getMiniatureSrc() {
+ return GET_THUMBNAIL_PATH.urlencode($this->getPath());
+ }
+
+ public function getPath() {
+ return $this->file_path;
+ }
+
+ private $file_path;
+ private $image;
+}
+
+class TileStack extends TileBase {
+
+ const STACK_REPRESENTATIVES = 3;
+
+ public function __construct($path_array, $stack_name) {
+ $this->tiles_array = array();
+ $this->stack_name = $stack_name;
+ for ($i = 0; $i < count($path_array) && $i < self::STACK_REPRESENTATIVES; $i++) {
+ $tile = new TileSingle($path_array[$i]);
+ array_push($this->tiles_array, $tile);
+ }
+ }
+
+ public function forceSize($width_must_fit=false) {
+ for ($i = 0; $i < count($this->tiles_array); $i++)
+ $this->tiles_array[$i]->forceSize(true);
+ }
+
+ public function getWidth() {
+ $max = 0;
+ for ($i = 0; $i < count($this->tiles_array); $i++) {
+ $max = max($max, $this->tiles_array[$i]->getWidth());
+ }
+ return min(200, $max);
+ }
+
+ public function get() {
+ $r = ''.$this->stack_name.'
';
+ for ($i = 0; $i < count($this->tiles_array); $i++) {
+ $top = rand(-5, 5);
+ $left = rand(-5, 5);
+ $img_w = $this->tiles_array[$i]->getWidth();
+ $extra = '';
+ if ($img_w < 200) {
+ $extra = 'width:'.$img_w.'px;';
+ }
+ $r .= '';
+// $r .= $this->tiles_array[$i]->get(' style="margin-top:'.$top.'px; margin-left:'.$left.'px; "');
+ }
+ return $r;
+ }
+
+ public function getOnHoverAction() {
+ return 'javascript:t(this);return false;';
+ }
+
+ public function getOnOutAction() {
+ return 'javascript:o(this);return false;';
+ }
+
+ public function getCount() {
+ return count($this->tiles_array);
+ }
+
+ private $tiles_array;
+ private $stack_name;
+}
+
+?>
diff --git a/apps/gallery/lib/tiles_test.php b/apps/gallery/lib/tiles_test.php
new file mode 100644
index 00000000000..022a88f75cc
--- /dev/null
+++ b/apps/gallery/lib/tiles_test.php
@@ -0,0 +1,87 @@
+
+
+
+
+
+addTile(new \OC\Pictures\TileSingle($images[$i]));
+ continue;
+ }
+ if (strcmp($prev_dir_arr[0], $dir_arr[0])!=0) {
+ $tl->addTile(new \OC\Pictures\TileStack($arr, $prev_dir_arr[0]));
+ $arr = array();
+ }
+ $arr[] = $root.$images[$i];
+ $previous_element = $images[$i];
+}
+
+$dir_arr = explode('/', $previous_element);
+
+if (count($dir_arr)==0) {
+ $tl->addTile(new \OC\Pictures\TileSingle($previous_element));
+} else if (count($dir_arr) && $ts->getCount() == 0){
+ $ts = new \OC\Pictures\TileStack(array($previous_element), $dir_arr[0]);
+} else {
+ $arr[] = $previous_element;
+ $ts->addTile($arr);
+}
+
+if ($ts->getCount() != 0) {
+ $tl->addTile($ts);
+}
+
+echo $tl->get();
+
+?>
diff --git a/apps/gallery/templates/index.php b/apps/gallery/templates/index.php
index 99af3bda0a3..55710038c0a 100644
--- a/apps/gallery/templates/index.php
+++ b/apps/gallery/templates/index.php
@@ -1,31 +1,86 @@
-
-
-
-
-
-
; ?>)
-
-
-
-
+
+
+
+
+addTile(new \OC\Pictures\TileSingle($root.$images[$i]));
+ continue;
+ }
+ if (strcmp($prev_dir_arr[0], $dir_arr[0])!=0) {
+ $tl->addTile(new \OC\Pictures\TileStack($arr, $prev_dir_arr[0]));
+ $arr = array();
+ }
+ $arr[] = $root.$images[$i];
+ $previous_element = $images[$i];
+}
+
+$dir_arr = explode('/', $previous_element);
+
+if (count($dir_arr)==0) {
+ $tl->addTile(new \OC\Pictures\TileSingle($previous_element));
+} else if (count($dir_arr) && $ts->getCount() == 0){
+ $ts = new \OC\Pictures\TileStack(array($root.$previous_element), $dir_arr[0]);
+} else {
+ $arr[] = $previous_element;
+ $ts->addTile($arr);
+}
+
+if ($ts->getCount() != 0) {
+ $tl->addTile($ts);
+}
+
+echo $tl->get();
+
+?>
diff --git a/lib/image.php b/lib/image.php
index a6bb92cea27..af61f9424e9 100644
--- a/lib/image.php
+++ b/lib/image.php
@@ -136,6 +136,8 @@ class OC_Image {
*/
private function _output($filepath=null) {
if($filepath) {
+ if (!file_exists(dirname($filepath)))
+ mkdir(dirname($filepath), 0777, true);
if(!is_writable(dirname($filepath))) {
OC_Log::write('core',__METHOD__.'(): Directory \''.dirname($filepath).'\' is not writable.', OC_Log::ERROR);
return false;
@@ -426,7 +428,7 @@ class OC_Image {
if(is_resource($str)) {
return false;
}
- $this->resource = imagecreatefromstring($str);
+ $this->resource = @imagecreatefromstring($str);
if(!$this->resource) {
OC_Log::write('core','OC_Image->loadFromData, couldn\'t load', OC_Log::DEBUG);
return false;
@@ -445,7 +447,7 @@ class OC_Image {
}
$data = base64_decode($str);
if($data) { // try to load from string data
- $this->resource = imagecreatefromstring($data);
+ $this->resource = @imagecreatefromstring($data);
if(!$this->resource) {
OC_Log::write('core','OC_Image->loadFromBase64, couldn\'t load', OC_Log::DEBUG);
return false;
@@ -496,6 +498,32 @@ class OC_Image {
return true;
}
+ public function preciseResize($width, $height) {
+ if (!$this->valid()) {
+ OC_Log::write('core',__METHOD__.'(): No image loaded', OC_Log::ERROR);
+ return false;
+ }
+ $width_orig=imageSX($this->resource);
+ $height_orig=imageSY($this->resource);
+ $process = imagecreatetruecolor($width, $height);
+
+ if ($process == false) {
+ OC_Log::write('core',__METHOD__.'(): Error creating true color image',OC_Log::ERROR);
+ imagedestroy($process);
+ return false;
+ }
+
+ imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
+ if ($process == false) {
+ OC_Log::write('core',__METHOD__.'(): Error resampling process image '.$width.'x'.$height,OC_Log::ERROR);
+ imagedestroy($process);
+ return false;
+ }
+ imagedestroy($this->resource);
+ $this->resource = $process;
+ return true;
+ }
+
/**
* @brief Crops the image to the middle square. If the image is already square it just returns.
* @param int maximum size for the result (optional)