setup image resize processor

This commit is contained in:
Alex Tran 2022-02-05 01:34:23 -06:00
parent 0020c7be94
commit 168676075f
8 changed files with 80 additions and 21 deletions

View file

@ -1,5 +1,5 @@
dev:
docker-compose -f ./server/docker-compose.yml up
update:
dev-update:
docker-compose -f ./server/docker-compose.yml up --build -V

View file

@ -35,7 +35,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
void getBackupInfo() async {
_updateServerInfo();
List<AssetPathEntity> list = await PhotoManager.getAssetPathList(onlyAll: true, type: RequestType.image);
List<AssetPathEntity> list = await PhotoManager.getAssetPathList(onlyAll: true, type: RequestType.common);
if (list.isEmpty) {
debugPrint("No Asset On Device");
@ -59,7 +59,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
// await PhotoManager.presentLimited();
// Gather assets info
List<AssetPathEntity> list =
await PhotoManager.getAssetPathList(hasAll: true, onlyAll: true, type: RequestType.image);
await PhotoManager.getAssetPathList(hasAll: true, onlyAll: true, type: RequestType.common);
if (list.isEmpty) {
debugPrint("No Asset On Device - Abort Backup Process");

View file

@ -12,7 +12,6 @@ import 'package:immich_mobile/utils/files_helper.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:http_parser/http_parser.dart';
import 'package:path/path.dart' as p;
import 'package:exif/exif.dart';
class BackupService {
final NetworkService _networkService = NetworkService();

View file

@ -22,7 +22,7 @@ import { AuthUserDto, GetAuthUser } from '../../decorators/auth-user.decorator';
import { CreateAssetDto } from './dto/create-asset.dto';
import { createReadStream } from 'fs';
import { ServeFileDto } from './dto/serve-file.dto';
import { ImageOptimizeService } from '../../modules/image-optimize/image-optimize.service';
import { AssetOptimizeService } from '../../modules/image-optimize/image-optimize.service';
import { AssetType } from './entities/asset.entity';
import { GetAllAssetQueryDto } from './dto/get-all-asset-query.dto';
@ -31,7 +31,7 @@ import { GetAllAssetQueryDto } from './dto/get-all-asset-query.dto';
export class AssetController {
constructor(
private readonly assetService: AssetService,
private readonly imageOptimizeService: ImageOptimizeService,
private readonly assetOptimizeService: AssetOptimizeService,
) {}
@Post('upload')
@ -45,7 +45,11 @@ export class AssetController {
const savedAsset = await this.assetService.createUserAsset(authUser, assetInfo, file.path, file.mimetype);
if (savedAsset && savedAsset.type == AssetType.IMAGE) {
await this.imageOptimizeService.resizeImage(savedAsset);
await this.assetOptimizeService.resizeImage(savedAsset);
}
if (savedAsset && savedAsset.type == AssetType.IMAGE) {
await this.assetOptimizeService.resizeVideo(savedAsset);
}
});

View file

@ -4,13 +4,13 @@ import { AssetController } from './asset.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AssetEntity } from './entities/asset.entity';
import { ImageOptimizeModule } from '../../modules/image-optimize/image-optimize.module';
import { ImageOptimizeService } from '../../modules/image-optimize/image-optimize.service';
import { AssetOptimizeService } from '../../modules/image-optimize/image-optimize.service';
import { BullModule } from '@nestjs/bull';
@Module({
imports: [
BullModule.registerQueue({
name: 'image',
name: 'optimize',
defaultJobOptions: {
attempts: 3,
removeOnComplete: true,
@ -29,7 +29,7 @@ import { BullModule } from '@nestjs/bull';
ImageOptimizeModule,
],
controllers: [AssetController],
providers: [AssetService, ImageOptimizeService],
providers: [AssetService, AssetOptimizeService],
exports: [],
})
export class AssetModule {}

View file

@ -6,13 +6,13 @@ import { AssetModule } from '../../api-v1/asset/asset.module';
import { AssetService } from '../../api-v1/asset/asset.service';
import { AssetEntity } from '../../api-v1/asset/entities/asset.entity';
import { ImageOptimizeProcessor } from './image-optimize.processor';
import { ImageOptimizeService } from './image-optimize.service';
import { AssetOptimizeService } from './image-optimize.service';
import { MachineLearningProcessor } from './machine-learning.processor';
@Module({
imports: [
BullModule.registerQueue({
name: 'image',
name: 'optimize',
defaultJobOptions: {
attempts: 3,
removeOnComplete: true,
@ -30,7 +30,7 @@ import { MachineLearningProcessor } from './machine-learning.processor';
TypeOrmModule.forFeature([AssetEntity]),
],
providers: [ImageOptimizeService, ImageOptimizeProcessor, MachineLearningProcessor],
exports: [ImageOptimizeService],
providers: [AssetOptimizeService, ImageOptimizeProcessor, MachineLearningProcessor],
exports: [AssetOptimizeService],
})
export class ImageOptimizeModule {}

View file

@ -8,7 +8,7 @@ import fs, { existsSync, mkdirSync } from 'fs';
import { ConfigService } from '@nestjs/config';
import { randomUUID } from 'crypto';
@Processor('image')
@Processor('optimize')
export class ImageOptimizeProcessor {
constructor(
@InjectRepository(AssetEntity) private assetRepository: Repository<AssetEntity>,
@ -16,8 +16,8 @@ export class ImageOptimizeProcessor {
private configService: ConfigService,
) {}
@Process('optimize')
async handleOptimization(job: Job) {
@Process('resize-image')
async resizeUploadedImage(job: Job) {
const { savedAsset }: { savedAsset: AssetEntity } = job.data;
const basePath = this.configService.get('UPLOAD_LOCATION');
@ -58,4 +58,46 @@ export class ImageOptimizeProcessor {
return 'ok';
}
@Process('resize-video')
async resizeUploadedVideo(job: Job) {
const { savedAsset }: { savedAsset: AssetEntity } = job.data;
const basePath = this.configService.get('UPLOAD_LOCATION');
const resizePath = savedAsset.originalPath.replace('/original/', '/thumb/');
// Create folder for thumb image if not exist
const resizeDir = `${basePath}/${savedAsset.userId}/thumb/${savedAsset.deviceId}`;
if (!existsSync(resizeDir)) {
mkdirSync(resizeDir, { recursive: true });
}
fs.readFile(savedAsset.originalPath, (err, data) => {
if (err) {
console.error('Error Reading File');
}
sharp(data)
.resize(512, 512, { fit: 'outside' })
.toFile(resizePath, async (err, info) => {
if (err) {
console.error('Error resizing file ', err);
}
await this.assetRepository.update(savedAsset, { resizePath: resizePath });
// Send file to object detection after resizing
// const detectionJob = await this.machineLearningQueue.add(
// 'object-detection',
// {
// resizePath,
// },
// { jobId: randomUUID() },
// );
});
});
return 'ok';
}
}

View file

@ -7,12 +7,26 @@ import { AssetEntity } from '../../api-v1/asset/entities/asset.entity';
import { AuthUserDto } from '../../decorators/auth-user.decorator';
@Injectable()
export class ImageOptimizeService {
constructor(@InjectQueue('image') private imageQueue: Queue) {}
export class AssetOptimizeService {
constructor(@InjectQueue('optimize') private optimizeQueue: Queue) {}
public async resizeImage(savedAsset: AssetEntity) {
const job = await this.imageQueue.add(
'optimize',
const job = await this.optimizeQueue.add(
'resize-image',
{
savedAsset,
},
{ jobId: randomUUID() },
);
return {
jobId: job.id,
};
}
public async resizeVideo(savedAsset: AssetEntity) {
const job = await this.optimizeQueue.add(
'resize-video',
{
savedAsset,
},