mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
improving performance
This commit is contained in:
parent
9f1490bc6d
commit
0500ad0e68
@ -85,7 +85,6 @@ export class ThumbnailGeneratorMWs {
|
||||
|
||||
const persons: PersonWithPhoto[] = req.resultPipe;
|
||||
for (let i = 0; i < persons.length; i++) {
|
||||
|
||||
// load parameters
|
||||
const mediaPath = path.join(ProjectPath.ImageFolder,
|
||||
persons[i].samplePhoto.directory.path,
|
||||
@ -151,8 +150,8 @@ export class ThumbnailGeneratorMWs {
|
||||
thPath: thPath,
|
||||
makeSquare: false,
|
||||
cut: {
|
||||
left: Math.round(Math.max(0, photo.metadata.faces[0].box.x - margin.x / 2)),
|
||||
top: Math.round(Math.max(0, photo.metadata.faces[0].box.y - margin.y / 2)),
|
||||
left: Math.round(Math.max(0, photo.metadata.faces[0].box.left - margin.x / 2)),
|
||||
top: Math.round(Math.max(0, photo.metadata.faces[0].box.top - margin.y / 2)),
|
||||
width: photo.metadata.faces[0].box.width + margin.x,
|
||||
height: photo.metadata.faces[0].box.height + margin.y
|
||||
},
|
||||
@ -208,7 +207,7 @@ export class ThumbnailGeneratorMWs {
|
||||
}
|
||||
|
||||
public static generatePersonThumbnailName(mediaPath: string, faceRegion: FaceRegion, size: number): string {
|
||||
return crypto.createHash('md5').update(mediaPath + '_' + faceRegion.name + '_' + faceRegion.box.x + '_' + faceRegion.box.y)
|
||||
return crypto.createHash('md5').update(mediaPath + '_' + faceRegion.name + '_' + faceRegion.box.left + '_' + faceRegion.box.top)
|
||||
.digest('hex') + '_' + size + '.jpg';
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ export interface IPersonManager {
|
||||
|
||||
keywordsToPerson(media: MediaDTO[]): Promise<void>;
|
||||
|
||||
updateCounts(): Promise<void>;
|
||||
onGalleryIndexUpdate(): Promise<void>;
|
||||
|
||||
updatePerson(name: string, partialPerson: PersonDTO): Promise<PersonEntry>;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ export class PersonManager implements IPersonManager {
|
||||
throw new Error('not supported by memory DB');
|
||||
}
|
||||
|
||||
updateCounts(): Promise<void> {
|
||||
onGalleryIndexUpdate(): Promise<void> {
|
||||
throw new Error('not supported by memory DB');
|
||||
}
|
||||
|
||||
|
@ -274,8 +274,8 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
directory: dir.id
|
||||
})
|
||||
.leftJoinAndSelect('face.person', 'person')
|
||||
.select(['face.id', 'face.box.x',
|
||||
'face.box.y', 'face.box.width', 'face.box.height',
|
||||
.select(['face.id', 'face.box.left',
|
||||
'face.box.top', 'face.box.width', 'face.box.height',
|
||||
'media.id', 'person.name', 'person.id'])
|
||||
.getMany();
|
||||
for (let i = 0; i < dir.media.length; i++) {
|
||||
|
@ -260,8 +260,8 @@ export class IndexingManager implements IIndexingManager {
|
||||
for (let j = 0; j < indexedFaces.length; j++) {
|
||||
if (indexedFaces[j].box.height === scannedFaces[i].box.height &&
|
||||
indexedFaces[j].box.width === scannedFaces[i].box.width &&
|
||||
indexedFaces[j].box.x === scannedFaces[i].box.x &&
|
||||
indexedFaces[j].box.y === scannedFaces[i].box.y &&
|
||||
indexedFaces[j].box.left === scannedFaces[i].box.left &&
|
||||
indexedFaces[j].box.top === scannedFaces[i].box.top &&
|
||||
indexedFaces[j].person.name === scannedFaces[i].name) {
|
||||
face = indexedFaces[j];
|
||||
indexedFaces.splice(j, 1);
|
||||
@ -289,7 +289,7 @@ export class IndexingManager implements IIndexingManager {
|
||||
await this.saveChildDirs(connection, currentDirId, scannedDirectory);
|
||||
await this.saveMedia(connection, currentDirId, scannedDirectory.media);
|
||||
await this.saveMetaFiles(connection, currentDirId, scannedDirectory);
|
||||
await ObjectManagers.getInstance().PersonManager.updateCounts();
|
||||
await ObjectManagers.getInstance().PersonManager.onGalleryIndexUpdate();
|
||||
await ObjectManagers.getInstance().VersionManager.updateDataVersion();
|
||||
} catch (e) {
|
||||
throw e;
|
||||
|
@ -6,10 +6,12 @@ import {PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {MediaEntity} from './enitites/MediaEntity';
|
||||
import {FaceRegionEntry} from './enitites/FaceRegionEntry';
|
||||
import {PersonDTO} from '../../../common/entities/PersonDTO';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
|
||||
const LOG_TAG = '[PersonManager]';
|
||||
|
||||
export class PersonManager implements IPersonManager {
|
||||
samplePhotos: { [key: string]: PhotoDTO } = {};
|
||||
persons: PersonEntry[] = [];
|
||||
|
||||
async updatePerson(name: string, partialPerson: PersonDTO): Promise<PersonEntry> {
|
||||
@ -34,22 +36,25 @@ export class PersonManager implements IPersonManager {
|
||||
}
|
||||
|
||||
async getSamplePhoto(name: string): Promise<PhotoDTO> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const rawAndEntities = await connection.getRepository(MediaEntity).createQueryBuilder('media')
|
||||
.limit(1)
|
||||
.leftJoinAndSelect('media.directory', 'directory')
|
||||
.leftJoinAndSelect('media.metadata.faces', 'faces')
|
||||
.leftJoinAndSelect('faces.person', 'person')
|
||||
.where('person.name LIKE :name COLLATE utf8_general_ci', {name: name}).getRawAndEntities();
|
||||
if (!this.samplePhotos[name]) {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const rawAndEntities = await connection.getRepository(MediaEntity).createQueryBuilder('media')
|
||||
.limit(1)
|
||||
.leftJoinAndSelect('media.directory', 'directory')
|
||||
.leftJoinAndSelect('media.metadata.faces', 'faces')
|
||||
.leftJoin('faces.person', 'person')
|
||||
.where('person.name LIKE :name COLLATE utf8_general_ci', {name: name}).getRawAndEntities();
|
||||
|
||||
if (rawAndEntities.entities.length === 0) {
|
||||
return null;
|
||||
if (rawAndEntities.entities.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const media: PhotoDTO = Utils.clone(rawAndEntities.entities[0]);
|
||||
|
||||
media.metadata.faces = [FaceRegionEntry.fromRawToDTO(rawAndEntities.raw[0])];
|
||||
|
||||
this.samplePhotos[name] = media;
|
||||
}
|
||||
const media: PhotoDTO = rawAndEntities.entities[0];
|
||||
|
||||
media.metadata.faces = [FaceRegionEntry.fromRawToDTO(rawAndEntities.raw[0])];
|
||||
|
||||
return media;
|
||||
return this.samplePhotos[name];
|
||||
|
||||
}
|
||||
|
||||
@ -129,6 +134,12 @@ export class PersonManager implements IPersonManager {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public async onGalleryIndexUpdate() {
|
||||
await this.updateCounts();
|
||||
this.samplePhotos = {};
|
||||
}
|
||||
|
||||
public async updateCounts() {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
await connection.query('update person_entry set count = ' +
|
||||
|
@ -9,9 +9,9 @@ export class FaceRegionBoxEntry implements FaceRegionBox {
|
||||
@Column('int')
|
||||
width: number;
|
||||
@Column('int')
|
||||
x: number;
|
||||
left: number;
|
||||
@Column('int')
|
||||
y: number;
|
||||
top: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,13 +42,13 @@ export class FaceRegionEntry {
|
||||
faces_personId: number,
|
||||
faces_boxHeight: number,
|
||||
faces_boxWidth: number,
|
||||
faces_boxX: number,
|
||||
faces_boxY: number,
|
||||
faces_boxLeft: number,
|
||||
faces_boxTop: number,
|
||||
person_id: number,
|
||||
person_name: string
|
||||
}): FaceRegion {
|
||||
return {
|
||||
box: {width: raw.faces_boxWidth, height: raw.faces_boxHeight, x: raw.faces_boxX, y: raw.faces_boxY},
|
||||
box: {width: raw.faces_boxWidth, height: raw.faces_boxHeight, left: raw.faces_boxLeft, top: raw.faces_boxTop},
|
||||
name: raw.person_name
|
||||
};
|
||||
}
|
||||
|
@ -211,12 +211,12 @@ export class MetadataLoader {
|
||||
const box = {
|
||||
width: Math.round(regionBox['stArea:w'] * metadata.size.width),
|
||||
height: Math.round(regionBox['stArea:h'] * metadata.size.height),
|
||||
x: Math.round(regionBox['stArea:x'] * metadata.size.width),
|
||||
y: Math.round(regionBox['stArea:y'] * metadata.size.height)
|
||||
left: Math.round(regionBox['stArea:x'] * metadata.size.width),
|
||||
top: Math.round(regionBox['stArea:y'] * metadata.size.height)
|
||||
};
|
||||
// convert center base box to corner based box
|
||||
box.x = Math.max(0, box.x - box.width / 2);
|
||||
box.y = Math.max(0, box.y - box.height / 2);
|
||||
box.left = Math.max(0, box.left - box.width / 2);
|
||||
box.top = Math.max(0, box.top - box.height / 2);
|
||||
faces.push({name: name, box: box});
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ export class PersonRouter {
|
||||
public static route(app: Express) {
|
||||
|
||||
this.updatePerson(app);
|
||||
this.addPersons(app);
|
||||
this.addGetPersons(app);
|
||||
this.getPersonThumbnail(app);
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ export class PersonRouter {
|
||||
);
|
||||
}
|
||||
|
||||
private static addPersons(app: Express) {
|
||||
private static addGetPersons(app: Express) {
|
||||
app.get(['/api/person'],
|
||||
// common part
|
||||
AuthenticationMWs.authenticate,
|
||||
|
@ -14,8 +14,8 @@ export interface PhotoDTO extends MediaDTO {
|
||||
export interface FaceRegionBox {
|
||||
width: number;
|
||||
height: number;
|
||||
x: number;
|
||||
y: number;
|
||||
left: number;
|
||||
top: number;
|
||||
}
|
||||
|
||||
export interface FaceRegion {
|
||||
|
@ -55,7 +55,6 @@ export class FaceComponent implements OnInit, OnDestroy {
|
||||
$event.preventDefault();
|
||||
$event.stopPropagation();
|
||||
await this.faceService.setFavourite(this.person, !this.person.isFavourite).catch(console.error);
|
||||
this.faceService.getPersons();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,9 @@ export class GridMedia extends Media {
|
||||
get Video(): VideoDTO {
|
||||
return <VideoDTO>this.media;
|
||||
}
|
||||
get Photo(): PhotoDTO {
|
||||
return <PhotoDTO>this.media;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -194,8 +194,8 @@ export class TestHelper {
|
||||
const f: FaceRegion = {
|
||||
name: rndStr() + '.jpg',
|
||||
box: {
|
||||
x: rndInt(),
|
||||
y: rndInt(),
|
||||
left: rndInt(),
|
||||
top: rndInt(),
|
||||
width: rndInt(),
|
||||
height: rndInt()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user