1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2024-12-25 02:04:15 +02:00

implementing thumbnail sizes

This commit is contained in:
Braun Patrik 2016-05-12 11:00:46 +02:00
parent d6b8b611b3
commit c66a9b49f3
19 changed files with 138 additions and 81 deletions

View File

@ -8,7 +8,6 @@ export var Config = new ConfigClass();
Config.Server = {
port: 80,
thumbnailSizes: [200],
imagesFolder: "/demo/images",
thumbnailFolder: "/demo/TEMP",
databaseType: DatabaseType.mongoDB

View File

@ -20,33 +20,47 @@ export class ThumbnailGeneratorMWs {
if (!req.resultPipe)
return next();
//load parameters
let imagePath = req.resultPipe;
let size:number = parseInt(req.params.size) || Config.Server.thumbnailSizes[0];
let size:number = parseInt(req.params.size) || Config.Client.thumbnailSizes[0];
let thumbnailFolder = ThumbnailGeneratorMWs.getThumbnailFolder();
if (Config.Server.thumbnailSizes.indexOf(size) === -1) {
size = Config.Server.thumbnailSizes[0];
//validate size
if (Config.Client.thumbnailSizes.indexOf(size) === -1) {
size = Config.Client.thumbnailSizes[0];
}
//generate thumbnail path
let thPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size));
req.resultPipe = thPath;
//check if thumbnail already exist
if (fs.existsSync(thPath) === true) {
return next();
}
//create thumbnail folder if not exist
if (!fs.existsSync(thumbnailFolder)) {
fs.mkdirSync(thumbnailFolder);
}
//generate thumbnail
Jimp.read(imagePath).then((image) => {
if (image.bitmap.with < image.bitmap.height) {
image.resize(size, Jimp.AUTO); // resize
} else {
image.resize(Jimp.AUTO, size); // resize
}
/**
* newWidth * newHeight = size*size
* newHeight/newWidth = height/width
*
* newHeight = (height/width)*newWidth
* newWidth * newWidth = (size*size) / (height/width)
*
* @type {number}
*/
let ratio = image.bitmap.height / image.bitmap.width;
let newWidth = Math.sqrt((size * size) / ratio);
image.resize(newWidth, Jimp.AUTO, Jimp.RESIZE_BEZIER);
image.quality(60); // set JPEG quality
image.write(thPath, () => { // save
@ -55,6 +69,7 @@ export class ThumbnailGeneratorMWs {
}).catch(function (err) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
});
}
private static generateThumbnailName(imagePath:string, size:number):string {

View File

@ -1,5 +1,10 @@
declare module "jimp" {
function read(filaname);
var RESIZE_NEAREST_NEIGHBOR;
var RESIZE_BILINEAR;
var RESIZE_BICUBIC;
var RESIZE_HERMITE;
var RESIZE_BEZIER;
var AUTO:any;
}

View File

@ -3,7 +3,6 @@
import * as _express from "express";
import * as _session from "express-session";
import * as _bodyParser from "body-parser";
import * as _compress from "compression";
import * as _debug from "debug";
import * as _http from "http";
import {PublicRouter} from "./routes/PublicRouter";
@ -29,6 +28,7 @@ export class Server {
this.debug = _debug("PiGallery2:server");
this.app = _express();
this.app.set('view engine', 'ejs');
if (process.env.DEBUG) {
@ -36,8 +36,6 @@ export class Server {
this.app.use(_morgan('dev'));
}
//enable gzip
this.app.use(_compress());
/**
* Session above all

View File

@ -56,4 +56,24 @@ export class Utils {
return arr;
}
public static findClosest(number:number, arr:Array<number>) {
let curr = arr[0];
let diff = Math.abs(number - curr);
arr.forEach((value)=> {
let newDiff = Math.abs(number - value);
if (newDiff < diff) {
diff = newDiff;
curr = value;
}
});
return curr;
}
}

View File

@ -4,7 +4,6 @@ export enum DatabaseType{
interface ServerConfig {
port:number;
thumbnailSizes:Array<number>;
imagesFolder:string;
thumbnailFolder:string;
databaseType:DatabaseType;
@ -17,6 +16,7 @@ interface SearchConfig {
}
interface ClientConfig {
thumbnailSizes:Array<number>;
Search:SearchConfig;
}
export class ConfigClass {
@ -24,6 +24,7 @@ export class ConfigClass {
public Server:ServerConfig = null;
public Client:ClientConfig = {
thumbnailSizes: [200, 400, 600],
Search: {
searchEnabled: true,
instantSearchEnabled: true,

View File

@ -1,14 +1,14 @@
import {Utils} from "../Utils";
import {Directory} from "./Directory";
export class Photo {
constructor(public id?:number, public name?:string, public directory?:Directory, public width?:number, public height?:number) {
}
public static getThumbnailPath(photo:Photo) {
/*public static getThumbnailPath(photo:Photo) {
return Utils.concatUrls("/api/gallery/content/", photo.directory.path, photo.directory.name, photo.name, "thumbnail");
}
public static getPhotoPath(photo:Photo) {
return Utils.concatUrls("/api/gallery/content/", photo.directory.path, photo.directory.name, photo.name);
}
}*/
}

View File

@ -0,0 +1,18 @@
import {Photo} from "../../../../common/entities/Photo";
import {Config} from "../../config/Config";
import {Utils} from "../../../../common/Utils";
export class GridPhoto {
constructor(public photo:Photo, public renderWidth:number, public renderHeight:number) {
}
getThumbnailPath() {
let renderSize = Math.sqrt(this.renderWidth * this.renderHeight);
let size = Utils.findClosest(renderSize, Config.Client.thumbnailSizes);
return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name, "thumbnail", size.toString());
}
getPhotoPath() {
return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name);
}
}

View File

@ -3,7 +3,8 @@ div {
line-height: normal;
font-size: 0;
}
gallery-photo {
gallery-grid-photo {
display: inline-block;
cursor: pointer;

View File

@ -1,12 +1,12 @@
<div #gridContainer (window:resize)="onResize()">
<gallery-photo
*ngFor="let gridPhoto of photosToRender"
(click)="lightbox.show(gridPhoto.photo)"
[photo]="gridPhoto.photo"
[style.width.px]="gridPhoto.renderWidth"
[style.height.px]="gridPhoto.renderHeight"
[style.marginLeft.px]="IMAGE_MARGIN"
[style.marginRight.px]="IMAGE_MARGIN">
<gallery-grid-photo
*ngFor="let gridPhoto of photosToRender"
(click)="lightbox.show(gridPhoto.photo)"
[gridPhoto]="gridPhoto"
[style.width.px]="gridPhoto.renderWidth"
[style.height.px]="gridPhoto.renderHeight"
[style.marginLeft.px]="IMAGE_MARGIN"
[style.marginRight.px]="IMAGE_MARGIN">
</gallery-photo>
</gallery-grid-photo>
</div>

View File

@ -11,9 +11,10 @@ import {
AfterViewInit
} from "@angular/core";
import {Photo} from "../../../../common/entities/Photo";
import {GalleryPhotoComponent} from "../photo/photo.gallery.component";
import {GridRowBuilder} from "./GridRowBuilder";
import {GalleryLightboxComponent} from "../lightbox/lightbox.gallery.component";
import {GridPhoto} from "./GridPhoto";
import {GalleryPhotoComponent} from "./photo/photo.grid.gallery.component";
@Component({
selector: 'gallery-grid',
@ -49,6 +50,8 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
ngAfterViewInit() {
this.lightbox.gridPhotoQL = this.gridPhotoQL;
//TODO: implement scroll detection
/* this.gridPhotoQL.changes.subscribe(
(x)=> {
console.log("changed");
@ -121,8 +124,4 @@ export class GalleryGridComponent implements OnChanges,AfterViewInit {
}
class GridPhoto {
constructor(public photo:Photo, public renderWidth:number, public renderHeight:number) {
}
}

View File

@ -0,0 +1 @@
<img #image [src]="gridPhoto.getThumbnailPath()">

View File

@ -0,0 +1,35 @@
///<reference path="../../../../browser.d.ts"/>
import {Component, Input, ElementRef, ViewChild} from "@angular/core";
import {IRenderable, Dimension} from "../../../model/IRenderable";
import {GridPhoto} from "../GridPhoto";
@Component({
selector: 'gallery-grid-photo',
templateUrl: 'app/gallery/grid/photo/photo.grid.gallery.component.html',
styleUrls: ['app/gallery/grid/photo/photo.grid.gallery.component.css'],
})
export class GalleryPhotoComponent implements IRenderable {
@Input() gridPhoto:GridPhoto;
@ViewChild("image") imageRef:ElementRef;
constructor() {
}
/* getPhotoPath() {
let renderSize = Math.sqrt(this.gridPhoto.renderWidth * this.gridPhoto.renderHeight);
let size = Utils.findClosest(renderSize, Config.Client.thumbnailSizes);
return Utils.concatUrls("/api/gallery/content/", this.gridPhoto.photo.directory.path, this.gridPhoto.photo.directory.name, this.gridPhoto.photo.name, "thumbnail", size.toString());
}
*/
public getDimension():Dimension {
return new Dimension(this.imageRef.nativeElement.offsetTop,
this.imageRef.nativeElement.offsetLeft,
this.imageRef.nativeElement.width,
this.imageRef.nativeElement.height);
}
}

View File

@ -2,7 +2,7 @@
import {Component, ElementRef, ViewChild, QueryList} from "@angular/core";
import {Photo} from "../../../../common/entities/Photo";
import {GalleryPhotoComponent} from "../photo/photo.gallery.component";
import {GalleryPhotoComponent} from "../grid/photo/photo.grid.gallery.component.ts";
import {AnimationBuilder} from "@angular/platform-browser/src/animate/animation_builder";
import {BrowserDomAdapter} from "@angular/platform-browser/src/browser_common";
import {Dimension} from "../../model/IRenderable";
@ -46,7 +46,7 @@ export class GalleryLightboxComponent {
let fromImage = {width: from.width + "px", height: from.height + "px", top: "0px", left: "0px"};
let toImage = this.calcLightBoxPhotoDimension(this.activePhoto.photo).toStyle();
let toImage = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo).toStyle();
this.forceAnimateFrom(fromImage,
toImage,
@ -89,7 +89,7 @@ export class GalleryLightboxComponent {
{display: "none"});
let fromImage = this.calcLightBoxPhotoDimension(this.activePhoto.photo).toStyle();
let fromImage = this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo).toStyle();
let toImage = {width: to.width + "px", height: to.height + "px", top: "0px", left: "0px"};
this.forceAnimateTo(fromImage,
@ -106,7 +106,7 @@ export class GalleryLightboxComponent {
let galleryPhotoComponents = this.gridPhotoQL.toArray();
let selectedPhoto:GalleryPhotoComponent = null;
for (let i = 0; i < galleryPhotoComponents.length; i++) {
if (galleryPhotoComponents[i].photo == photo) {
if (galleryPhotoComponents[i].gridPhoto.photo == photo) {
selectedPhoto = galleryPhotoComponents[i];
break;
}
@ -150,14 +150,14 @@ export class GalleryLightboxComponent {
if (!this.activePhoto) {
return "";
}
return Photo.getPhotoPath(this.activePhoto.photo);
return this.activePhoto.gridPhoto.getPhotoPath();
}
getThumbnailPath() {
if (!this.activePhoto) {
return "";
}
return Photo.getThumbnailPath(this.activePhoto.photo);
return this.activePhoto.gridPhoto.getThumbnailPath();
}
private getBodyScrollTop() {

View File

@ -1 +0,0 @@
<img #image [src]="getPhotoPath()">

View File

@ -1,32 +0,0 @@
///<reference path="../../../browser.d.ts"/>
import {Component, Input, ElementRef, ViewChild} from "@angular/core";
import {Photo} from "../../../../common/entities/Photo";
import {IRenderable, Dimension} from "../../model/IRenderable";
@Component({
selector: 'gallery-photo',
templateUrl: 'app/gallery/photo/photo.gallery.component.html',
styleUrls: ['app/gallery/photo/photo.gallery.component.css'],
})
export class GalleryPhotoComponent implements IRenderable {
@Input() photo:Photo;
@ViewChild("image") imageRef:ElementRef;
constructor() {
}
getPhotoPath() {
return Photo.getThumbnailPath(this.photo);
}
public getDimension():Dimension {
return new Dimension(this.imageRef.nativeElement.offsetTop,
this.imageRef.nativeElement.offsetLeft,
this.imageRef.nativeElement.width,
this.imageRef.nativeElement.height);
}
}

View File

@ -31,9 +31,8 @@
"@angular/platform-server": "2.0.0-rc.1",
"@angular/router": "2.0.0-rc.1",
"@angular/router-deprecated": "2.0.0-rc.1",
"body-parser": "^1.15.0",
"compression": "^1.6.1",
"core-js": "^2.3.0",
"body-parser": "^1.15.1",
"core-js": "^2.4.0",
"debug": "^2.2.0",
"ejs": "^2.4.1",
"express": "^4.13.4",
@ -41,13 +40,13 @@
"image-size": "^0.5.0",
"jimp": "^0.2.24",
"mime": "^1.3.4",
"mongoose": "^4.4.14",
"mongoose": "^4.4.16",
"morgan": "^1.7.0",
"ng2-cookies": "^0.1.5",
"optimist": "^0.6.1",
"rxjs": "5.0.0-beta.6",
"ts-loader": "^0.8.2",
"tslint": "^3.9.0",
"tslint": "^3.10.1",
"typescript": "^1.8.10",
"typings": "^0.8.1",
"webpack": "^1.13.0",
@ -67,10 +66,10 @@
"jasmine-core": "^2.4.1",
"json-loader": "^0.5.4",
"karma": "^0.13.21",
"karma-coverage": "^0.5.3",
"karma-coverage": "^1.0.0",
"karma-coveralls": "^1.1.2",
"karma-jasmine": "^0.3.7",
"karma-mocha-reporter": "^2.0.0",
"karma-jasmine": "^1.0.2",
"karma-mocha-reporter": "^2.0.3",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "1.7.0",

View File

@ -3,7 +3,6 @@
"version": false,
"ambientDependencies": {
"body-parser": "registry:dt/body-parser#0.0.0+20160317120654",
"compression": "registry:dt/compression#0.0.0+20160501162003",
"core-js": "registry:dt/core-js#0.0.0+20160317120654",
"debug": "github:DefinitelyTyped/DefinitelyTyped/debug/debug.d.ts#0d622d857f97d44ea7dcad2b3edec1f23c48fe9e",
"express": "github:DefinitelyTyped/DefinitelyTyped/express/express.d.ts#0d622d857f97d44ea7dcad2b3edec1f23c48fe9e",