diff --git a/services/api.service.ts b/services/api.service.ts index 7bd0ce6..1d1d856 100644 --- a/services/api.service.ts +++ b/services/api.service.ts @@ -121,7 +121,7 @@ export default class ApiService extends Service { usePolling: true, ignoreInitial: true, atomic: true, - depth: 1, + depth: 10, awaitWriteFinish: { stabilityThreshold: 2000, pollInterval: 100, diff --git a/services/imagetransformation.service.ts b/services/imagetransformation.service.ts index 468cf40..fdaa265 100644 --- a/services/imagetransformation.service.ts +++ b/services/imagetransformation.service.ts @@ -8,7 +8,7 @@ import { Errors, } from "moleculer"; import path from "path"; -import { analyze, resizeImage } from "../utils/imagetransformation.utils"; +import { analyze, getColorHistogramData, resizeImage } from "../utils/imagetransformation.utils"; export default class ImageTransformation extends Service { // @ts-ignore public constructor( @@ -62,9 +62,15 @@ export default class ImageTransformation extends Service { const url = new URL(ctx.params.imageFilePath); const pathName = url.pathname; const decodedImageFileURI = decodeURI(pathName); - + const finalImagePath = path.resolve("." + decodedImageFileURI); - return await analyze(path.resolve("." + decodedImageFileURI)); + const analyzedData = await analyze(finalImagePath); + const colorHistogramData = await getColorHistogramData(finalImagePath, false); + + return { + analyzedData, + colorHistogramData, + } }, }, }, diff --git a/services/library.service.ts b/services/library.service.ts index e279a54..5eaad7a 100644 --- a/services/library.service.ts +++ b/services/library.service.ts @@ -157,8 +157,8 @@ export default class ImportService extends Service { }; }; inferredMetadata: { - issue: Object, - }, + issue: Object; + }; rawFileDetails: { name: string; }; @@ -166,7 +166,7 @@ export default class ImportService extends Service { ) { let volumeDetails; const comicMetadata = ctx.params; - + // When an issue is added from the search CV feature if ( comicMetadata.sourcedMetadata.comicvine && @@ -191,7 +191,7 @@ export default class ImportService extends Service { resolve(data); } else if (error) { console.log("data", data); - console.log("error", error) + console.log("error", error); throw new Errors.MoleculerError( "Failed to import comic book", 400, @@ -400,7 +400,7 @@ export default class ImportService extends Service { ]; }> ) => { - // 2a. Enqueue the Elasticsearch job + // 2a. Elasticsearch query const { queryObjects } = ctx.params; // construct the query for ElasticSearch let elasticSearchQuery = {}; @@ -426,7 +426,10 @@ export default class ImportService extends Service { { term: { "inferredMetadata.issue.number": - parseInt(queryObject.issueNumber, 10), + parseInt( + queryObject.issueNumber, + 10 + ), }, }, ], @@ -438,29 +441,8 @@ export default class ImportService extends Service { index: "comics", search_type: "dfs_query_then_fetch", }, - // { issueId: queryObject.issueId }, { query: elasticSearchQuery, - // script_fields: { - // issueId: { - // script: { - // lang: "painless", - // params: { - // match: { - // issueId: - // queryObject.issueId, - // }, - // }, - // inline: "params.match", - // }, - // }, - // fileName: { - // script: { - // lang: "painless", - // inline: "params['_source']['rawFileDetails']", - // }, - // }, - // }, }, ]; } @@ -473,11 +455,15 @@ export default class ImportService extends Service { elasticSearchQueries, queryObjects, }); - // await ctx.broker.call("queue.issuesForSeries", { - // elasticSearchQueries, - // }); }, }, + libraryStatistics: { + rest: "GET /libraryStatistics", + params: {}, + handler: async (ctx: Context<{}>) => { + + } + }, flushDB: { rest: "POST /flushDB", params: {}, diff --git a/utils/imagetransformation.utils.ts b/utils/imagetransformation.utils.ts index 63ca313..c7710b5 100644 --- a/utils/imagetransformation.utils.ts +++ b/utils/imagetransformation.utils.ts @@ -35,7 +35,10 @@ export const resizeImage = async ( return err; } - console.log("Image file resized with the following parameters: %o", info); + console.log( + "Image file resized with the following parameters: %o", + info + ); return info; }); }; @@ -44,7 +47,63 @@ export const analyze = async (inputFilePath: string | Buffer) => { const stats = await sharp(inputFilePath).stats(); // const { r, g, b } = dominant; return stats; -} +}; + +export const getColorHistogramData = async ( + inputFilePath: string | Buffer, + isValueHistogram: Boolean +) => { + const { data, info } = await sharp(inputFilePath) + // output the raw pixels + .raw() + .toBuffer({ resolveWithObject: true }); + const src = new Uint32Array(data.buffer); + // const src = new Uint8ClampedArray(data.buffer); + console.log(src); + + let histBrightness = new Array(256).fill(0); + let histR = new Array(256).fill(0); + let histG = new Array(256).fill(0); + let histB = new Array(256).fill(0); + + for (let i = 0; i < src.length; i++) { + let r = src[i] & 0xff; + let g = (src[i] >> 8) & 0xff; + let b = (src[i] >> 16) & 0xff; + histBrightness[r]++; + histBrightness[g]++; + histBrightness[b]++; + histR[r]++; + histG[g]++; + histB[b]++; + } + + let maxBrightness = 0; + if (isValueHistogram) { + for (let i = 1; i < 256; i++) { + if (maxBrightness < histBrightness[i]) { + maxBrightness = histBrightness[i]; + } + } + } else { + for (let i = 0; i < 256; i++) { + if (maxBrightness < histR[i]) { + maxBrightness = histR[i]; + } else if (maxBrightness < histG[i]) { + maxBrightness = histG[i]; + } else if (maxBrightness < histB[i]) { + maxBrightness = histB[i]; + } + } + } + + return { + r: histR, + g: histG, + b: histB, + maxBrightness, + }; +}; export const calculateLevenshteinDistance = async ( imagePath1: string,