@midscene/shared
Advanced tools
Comparing version 0.5.2-beta-20241010035503.0 to 0.5.2
@@ -39,2 +39,5 @@ // src/img/info.ts | ||
} | ||
function base64ToPngFormat(base64) { | ||
return `data:image/png;base64,${base64}`; | ||
} | ||
@@ -119,17 +122,30 @@ // src/img/transform.ts | ||
const colors = [ | ||
{ rect: 65535, text: 4294967295 }, | ||
// blue, white | ||
{ rect: 2336560127, text: 4294967295 } | ||
// brown, white | ||
{ rect: 4278190335, text: 4294967295 } | ||
// red, white | ||
// { rect: 0x0000ffff, text: 0xffffffff }, // blue, white | ||
// { rect: 0x8b4513ff, text: 0xffffffff }, // brown, white | ||
]; | ||
const boxPadding = 5; | ||
for (let index = 0; index < elements2.length; index++) { | ||
const element = elements2[index]; | ||
const color = colors[index % colors.length]; | ||
const paddedRect = { | ||
left: Math.max(0, element.rect.left - boxPadding), | ||
top: Math.max(0, element.rect.top - boxPadding), | ||
width: Math.min( | ||
imageWidth2 - element.rect.left, | ||
element.rect.width + boxPadding * 2 | ||
), | ||
height: Math.min( | ||
imageHeight2 - element.rect.top, | ||
element.rect.height + boxPadding * 2 | ||
) | ||
}; | ||
image.scan( | ||
element.x, | ||
element.y, | ||
element.width, | ||
element.height, | ||
paddedRect.left, | ||
paddedRect.top, | ||
paddedRect.width, | ||
paddedRect.height, | ||
function(x, y, idx) { | ||
if (x === element.x || x === element.x + element.width - 1 || y === element.y || y === element.y + element.height - 1) { | ||
if (x === paddedRect.left || x === paddedRect.left + paddedRect.width - 1 || y === paddedRect.top || y === paddedRect.top + paddedRect.height - 1) { | ||
this.bitmap.data[idx + 0] = color.rect >> 24 & 255; | ||
@@ -142,11 +158,11 @@ this.bitmap.data[idx + 1] = color.rect >> 16 & 255; | ||
); | ||
const textWidth = element.label.length * 8; | ||
const textWidth = element.indexId.toString().length * 8; | ||
const textHeight = 12; | ||
const rectWidth = textWidth + 5; | ||
const rectHeight = textHeight + 4; | ||
let rectX = element.x - rectWidth; | ||
let rectY = element.y + element.height / 2 - textHeight / 2 - 2; | ||
let rectX = paddedRect.left - rectWidth; | ||
let rectY = paddedRect.top + paddedRect.height / 2 - textHeight / 2 - 2; | ||
if (rectX < 0) { | ||
rectX = element.x; | ||
rectY = element.y - rectHeight; | ||
rectX = paddedRect.left; | ||
rectY = paddedRect.top - rectHeight; | ||
} | ||
@@ -165,3 +181,3 @@ image.scan(rectX, rectY, rectWidth, rectHeight, function(x, y, idx) { | ||
{ | ||
text: element.label, | ||
text: element.indexId.toString(), | ||
alignmentX: Jimp3.HORIZONTAL_ALIGN_CENTER, | ||
@@ -178,59 +194,56 @@ alignmentY: Jimp3.VERTICAL_ALIGN_MIDDLE | ||
}; | ||
var processImageElementInfo = async (options) => { | ||
const base64Image = options.inputImgBase64.split(";base64,").pop(); | ||
assert2(base64Image, "base64Image is undefined"); | ||
const imageBuffer = Buffer3.from(base64Image, "base64"); | ||
var compositeElementInfoImg = async (options) => { | ||
const { inputImgBase64, elementsPositionInfo } = options; | ||
const imageBuffer = Buffer3.from(inputImgBase64, "base64"); | ||
const image = await Jimp3.read(imageBuffer); | ||
const { width, height } = image.bitmap; | ||
if (width && height) { | ||
const svgOverlay = await createSvgOverlay( | ||
options.elementsPositionInfo, | ||
width, | ||
height | ||
); | ||
const svgOverlayWithoutText = await createSvgOverlay( | ||
options.elementsPositionInfoWithoutText, | ||
width, | ||
height | ||
); | ||
const compositeElementInfoImgBase64 = await Jimp3.read(imageBuffer).then(async (image2) => { | ||
const svgImage = await Jimp3.read(svgOverlay); | ||
return image2.composite(svgImage, 0, 0, { | ||
mode: Jimp3.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1 | ||
}); | ||
}).then((compositeImage) => { | ||
return compositeImage.getBufferAsync(Jimp3.MIME_PNG); | ||
}).then((buffer) => { | ||
return buffer.toString("base64"); | ||
}).catch((error) => { | ||
throw error; | ||
if (!width || !height) { | ||
throw Error("Image processing failed because width or height is undefined"); | ||
} | ||
const svgOverlay = await createSvgOverlay( | ||
elementsPositionInfo, | ||
width, | ||
height | ||
); | ||
return await Jimp3.read(imageBuffer).then(async (image2) => { | ||
const svgImage = await Jimp3.read(svgOverlay); | ||
return image2.composite(svgImage, 0, 0, { | ||
mode: Jimp3.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1 | ||
}); | ||
const compositeElementInfoImgWithoutTextBase64 = await Jimp3.read( | ||
imageBuffer | ||
).then(async (image2) => { | ||
const svgImage = await Jimp3.read(svgOverlayWithoutText); | ||
return image2.composite(svgImage, 0, 0, { | ||
mode: Jimp3.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1 | ||
}); | ||
}).then((compositeImage) => { | ||
return compositeImage.getBufferAsync(Jimp3.MIME_PNG); | ||
}).then((buffer) => { | ||
return buffer.toString("base64"); | ||
}).catch((error) => { | ||
throw error; | ||
}); | ||
return { | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64 | ||
}; | ||
} | ||
throw Error("Image processing failed because width or height is undefined"); | ||
}).then((compositeImage) => { | ||
return compositeImage.getBufferAsync(Jimp3.MIME_PNG); | ||
}).then((buffer) => { | ||
return buffer.toString("base64"); | ||
}).catch((error) => { | ||
throw error; | ||
}); | ||
}; | ||
var processImageElementInfo = async (options) => { | ||
const base64Image = options.inputImgBase64.split(";base64,").pop(); | ||
assert2(base64Image, "base64Image is undefined"); | ||
const [ | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64 | ||
] = await Promise.all([ | ||
compositeElementInfoImg({ | ||
inputImgBase64: options.inputImgBase64, | ||
elementsPositionInfo: options.elementsPositionInfo | ||
}), | ||
compositeElementInfoImg({ | ||
inputImgBase64: options.inputImgBase64, | ||
elementsPositionInfo: options.elementsPositionInfoWithoutText | ||
}) | ||
]); | ||
return { | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64 | ||
}; | ||
}; | ||
export { | ||
base64Encoded, | ||
base64ToPngFormat, | ||
calculateNewDimensions, | ||
compositeElementInfoImg, | ||
imageInfo, | ||
@@ -237,0 +250,0 @@ imageInfoOfBase64, |
@@ -34,3 +34,5 @@ "use strict"; | ||
base64Encoded: () => base64Encoded, | ||
base64ToPngFormat: () => base64ToPngFormat, | ||
calculateNewDimensions: () => calculateNewDimensions, | ||
compositeElementInfoImg: () => compositeElementInfoImg, | ||
imageInfo: () => imageInfo, | ||
@@ -84,2 +86,5 @@ imageInfoOfBase64: () => imageInfoOfBase64, | ||
} | ||
function base64ToPngFormat(base64) { | ||
return `data:image/png;base64,${base64}`; | ||
} | ||
@@ -164,17 +169,30 @@ // src/img/transform.ts | ||
const colors = [ | ||
{ rect: 65535, text: 4294967295 }, | ||
// blue, white | ||
{ rect: 2336560127, text: 4294967295 } | ||
// brown, white | ||
{ rect: 4278190335, text: 4294967295 } | ||
// red, white | ||
// { rect: 0x0000ffff, text: 0xffffffff }, // blue, white | ||
// { rect: 0x8b4513ff, text: 0xffffffff }, // brown, white | ||
]; | ||
const boxPadding = 5; | ||
for (let index = 0; index < elements2.length; index++) { | ||
const element = elements2[index]; | ||
const color = colors[index % colors.length]; | ||
const paddedRect = { | ||
left: Math.max(0, element.rect.left - boxPadding), | ||
top: Math.max(0, element.rect.top - boxPadding), | ||
width: Math.min( | ||
imageWidth2 - element.rect.left, | ||
element.rect.width + boxPadding * 2 | ||
), | ||
height: Math.min( | ||
imageHeight2 - element.rect.top, | ||
element.rect.height + boxPadding * 2 | ||
) | ||
}; | ||
image.scan( | ||
element.x, | ||
element.y, | ||
element.width, | ||
element.height, | ||
paddedRect.left, | ||
paddedRect.top, | ||
paddedRect.width, | ||
paddedRect.height, | ||
function(x, y, idx) { | ||
if (x === element.x || x === element.x + element.width - 1 || y === element.y || y === element.y + element.height - 1) { | ||
if (x === paddedRect.left || x === paddedRect.left + paddedRect.width - 1 || y === paddedRect.top || y === paddedRect.top + paddedRect.height - 1) { | ||
this.bitmap.data[idx + 0] = color.rect >> 24 & 255; | ||
@@ -187,11 +205,11 @@ this.bitmap.data[idx + 1] = color.rect >> 16 & 255; | ||
); | ||
const textWidth = element.label.length * 8; | ||
const textWidth = element.indexId.toString().length * 8; | ||
const textHeight = 12; | ||
const rectWidth = textWidth + 5; | ||
const rectHeight = textHeight + 4; | ||
let rectX = element.x - rectWidth; | ||
let rectY = element.y + element.height / 2 - textHeight / 2 - 2; | ||
let rectX = paddedRect.left - rectWidth; | ||
let rectY = paddedRect.top + paddedRect.height / 2 - textHeight / 2 - 2; | ||
if (rectX < 0) { | ||
rectX = element.x; | ||
rectY = element.y - rectHeight; | ||
rectX = paddedRect.left; | ||
rectY = paddedRect.top - rectHeight; | ||
} | ||
@@ -210,3 +228,3 @@ image.scan(rectX, rectY, rectWidth, rectHeight, function(x, y, idx) { | ||
{ | ||
text: element.label, | ||
text: element.indexId.toString(), | ||
alignmentX: import_jimp3.default.HORIZONTAL_ALIGN_CENTER, | ||
@@ -223,60 +241,57 @@ alignmentY: import_jimp3.default.VERTICAL_ALIGN_MIDDLE | ||
}; | ||
var processImageElementInfo = async (options) => { | ||
const base64Image = options.inputImgBase64.split(";base64,").pop(); | ||
(0, import_node_assert2.default)(base64Image, "base64Image is undefined"); | ||
const imageBuffer = import_node_buffer3.Buffer.from(base64Image, "base64"); | ||
var compositeElementInfoImg = async (options) => { | ||
const { inputImgBase64, elementsPositionInfo } = options; | ||
const imageBuffer = import_node_buffer3.Buffer.from(inputImgBase64, "base64"); | ||
const image = await import_jimp3.default.read(imageBuffer); | ||
const { width, height } = image.bitmap; | ||
if (width && height) { | ||
const svgOverlay = await createSvgOverlay( | ||
options.elementsPositionInfo, | ||
width, | ||
height | ||
); | ||
const svgOverlayWithoutText = await createSvgOverlay( | ||
options.elementsPositionInfoWithoutText, | ||
width, | ||
height | ||
); | ||
const compositeElementInfoImgBase64 = await import_jimp3.default.read(imageBuffer).then(async (image2) => { | ||
const svgImage = await import_jimp3.default.read(svgOverlay); | ||
return image2.composite(svgImage, 0, 0, { | ||
mode: import_jimp3.default.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1 | ||
}); | ||
}).then((compositeImage) => { | ||
return compositeImage.getBufferAsync(import_jimp3.default.MIME_PNG); | ||
}).then((buffer) => { | ||
return buffer.toString("base64"); | ||
}).catch((error) => { | ||
throw error; | ||
if (!width || !height) { | ||
throw Error("Image processing failed because width or height is undefined"); | ||
} | ||
const svgOverlay = await createSvgOverlay( | ||
elementsPositionInfo, | ||
width, | ||
height | ||
); | ||
return await import_jimp3.default.read(imageBuffer).then(async (image2) => { | ||
const svgImage = await import_jimp3.default.read(svgOverlay); | ||
return image2.composite(svgImage, 0, 0, { | ||
mode: import_jimp3.default.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1 | ||
}); | ||
const compositeElementInfoImgWithoutTextBase64 = await import_jimp3.default.read( | ||
imageBuffer | ||
).then(async (image2) => { | ||
const svgImage = await import_jimp3.default.read(svgOverlayWithoutText); | ||
return image2.composite(svgImage, 0, 0, { | ||
mode: import_jimp3.default.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1 | ||
}); | ||
}).then((compositeImage) => { | ||
return compositeImage.getBufferAsync(import_jimp3.default.MIME_PNG); | ||
}).then((buffer) => { | ||
return buffer.toString("base64"); | ||
}).catch((error) => { | ||
throw error; | ||
}); | ||
return { | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64 | ||
}; | ||
} | ||
throw Error("Image processing failed because width or height is undefined"); | ||
}).then((compositeImage) => { | ||
return compositeImage.getBufferAsync(import_jimp3.default.MIME_PNG); | ||
}).then((buffer) => { | ||
return buffer.toString("base64"); | ||
}).catch((error) => { | ||
throw error; | ||
}); | ||
}; | ||
var processImageElementInfo = async (options) => { | ||
const base64Image = options.inputImgBase64.split(";base64,").pop(); | ||
(0, import_node_assert2.default)(base64Image, "base64Image is undefined"); | ||
const [ | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64 | ||
] = await Promise.all([ | ||
compositeElementInfoImg({ | ||
inputImgBase64: options.inputImgBase64, | ||
elementsPositionInfo: options.elementsPositionInfo | ||
}), | ||
compositeElementInfoImg({ | ||
inputImgBase64: options.inputImgBase64, | ||
elementsPositionInfo: options.elementsPositionInfoWithoutText | ||
}) | ||
]); | ||
return { | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64 | ||
}; | ||
}; | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
base64Encoded, | ||
base64ToPngFormat, | ||
calculateNewDimensions, | ||
compositeElementInfoImg, | ||
imageInfo, | ||
@@ -283,0 +298,0 @@ imageInfoOfBase64, |
import { Buffer } from 'node:buffer'; | ||
import { NodeType } from './constants.js'; | ||
interface Size { | ||
interface Size$1 { | ||
width: number; | ||
@@ -15,3 +15,3 @@ height: number; | ||
*/ | ||
declare function imageInfo(image: string | Buffer): Promise<Size>; | ||
declare function imageInfo(image: string | Buffer): Promise<Size$1>; | ||
/** | ||
@@ -24,3 +24,3 @@ * Retrieves the dimensions of an image from a base64-encoded string | ||
*/ | ||
declare function imageInfoOfBase64(imageBase64: string): Promise<Size>; | ||
declare function imageInfoOfBase64(imageBase64: string): Promise<Size$1>; | ||
/** | ||
@@ -37,2 +37,3 @@ * Encodes an image file to a base64 encoded string | ||
declare function base64Encoded(image: string, withHeader?: boolean): string; | ||
declare function base64ToPngFormat(base64: string): string; | ||
@@ -97,13 +98,27 @@ /** | ||
type ElementType = { | ||
x: number; | ||
y: number; | ||
interface Point { | ||
left: number; | ||
top: number; | ||
} | ||
interface Size { | ||
width: number; | ||
height: number; | ||
label: string; | ||
} | ||
type Rect = Point & Size; | ||
type ElementType = { | ||
locator: string; | ||
rect: Rect; | ||
center: [number, number]; | ||
id: string; | ||
indexId: number; | ||
attributes: { | ||
nodeType: NodeType; | ||
[key: string]: string; | ||
nodeType: NodeType; | ||
}; | ||
}; | ||
declare const compositeElementInfoImg: (options: { | ||
inputImgBase64: string; | ||
elementsPositionInfo: Array<ElementType>; | ||
}) => Promise<string>; | ||
declare const processImageElementInfo: (options: { | ||
@@ -118,2 +133,2 @@ inputImgBase64: string; | ||
export { base64Encoded, calculateNewDimensions, imageInfo, imageInfoOfBase64, processImageElementInfo, resizeImg, saveBase64Image, transformImgPathToBase64, trimImage }; | ||
export { base64Encoded, base64ToPngFormat, calculateNewDimensions, compositeElementInfoImg, imageInfo, imageInfoOfBase64, processImageElementInfo, resizeImg, saveBase64Image, transformImgPathToBase64, trimImage }; |
{ | ||
"name": "@midscene/shared", | ||
"version": "0.5.2-beta-20241010035503.0", | ||
"version": "0.5.2", | ||
"types": "./dist/types/index.d.ts", | ||
@@ -5,0 +5,0 @@ "main": "./dist/lib/index.js", |
import assert from 'node:assert'; | ||
import { Buffer } from 'node:buffer'; | ||
import type { Rect } from '@/types'; | ||
import Jimp from 'jimp'; | ||
@@ -8,10 +9,15 @@ import type { NodeType } from '../constants'; | ||
type ElementType = { | ||
x: number; | ||
y: number; | ||
width: number; | ||
height: number; | ||
label: string; | ||
locator: string; | ||
rect: Rect; | ||
center: [number, number]; | ||
id: string; | ||
indexId: number; | ||
attributes: { | ||
nodeType: NodeType; | ||
[key: string]: string; | ||
nodeType: NodeType; | ||
}; | ||
@@ -34,6 +40,8 @@ }; | ||
const colors = [ | ||
{ rect: 0x0000ffff, text: 0xffffffff }, // blue, white | ||
{ rect: 0x8b4513ff, text: 0xffffffff }, // brown, white | ||
{ rect: 0xff0000ff, text: 0xffffffff }, // red, white | ||
// { rect: 0x0000ffff, text: 0xffffffff }, // blue, white | ||
// { rect: 0x8b4513ff, text: 0xffffffff }, // brown, white | ||
]; | ||
const boxPadding = 5; | ||
for (let index = 0; index < elements.length; index++) { | ||
@@ -43,14 +51,28 @@ const element = elements[index]; | ||
// Add 5px padding to the rect | ||
const paddedRect = { | ||
left: Math.max(0, element.rect.left - boxPadding), | ||
top: Math.max(0, element.rect.top - boxPadding), | ||
width: Math.min( | ||
imageWidth - element.rect.left, | ||
element.rect.width + boxPadding * 2, | ||
), | ||
height: Math.min( | ||
imageHeight - element.rect.top, | ||
element.rect.height + boxPadding * 2, | ||
), | ||
}; | ||
// Draw rectangle | ||
image.scan( | ||
element.x, | ||
element.y, | ||
element.width, | ||
element.height, | ||
paddedRect.left, | ||
paddedRect.top, | ||
paddedRect.width, | ||
paddedRect.height, | ||
function (x, y, idx) { | ||
if ( | ||
x === element.x || | ||
x === element.x + element.width - 1 || | ||
y === element.y || | ||
y === element.y + element.height - 1 | ||
x === paddedRect.left || | ||
x === paddedRect.left + paddedRect.width - 1 || | ||
y === paddedRect.top || | ||
y === paddedRect.top + paddedRect.height - 1 | ||
) { | ||
@@ -66,13 +88,13 @@ this.bitmap.data[idx + 0] = (color.rect >> 24) & 0xff; // R | ||
// Calculate text position | ||
const textWidth = element.label.length * 8; | ||
const textWidth = element.indexId.toString().length * 8; | ||
const textHeight = 12; | ||
const rectWidth = textWidth + 5; | ||
const rectHeight = textHeight + 4; | ||
let rectX = element.x - rectWidth; | ||
let rectY = element.y + element.height / 2 - textHeight / 2 - 2; | ||
let rectX = paddedRect.left - rectWidth; | ||
let rectY = paddedRect.top + paddedRect.height / 2 - textHeight / 2 - 2; | ||
// Check if obscured by the left | ||
if (rectX < 0) { | ||
rectX = element.x; | ||
rectY = element.y - rectHeight; | ||
rectX = paddedRect.left; | ||
rectY = paddedRect.top - rectHeight; | ||
} | ||
@@ -94,3 +116,3 @@ | ||
{ | ||
text: element.label, | ||
text: element.indexId.toString(), | ||
alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER, | ||
@@ -110,2 +132,42 @@ alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE, | ||
export const compositeElementInfoImg = async (options: { | ||
inputImgBase64: string; | ||
elementsPositionInfo: Array<ElementType>; | ||
}) => { | ||
const { inputImgBase64, elementsPositionInfo } = options; | ||
const imageBuffer = Buffer.from(inputImgBase64, 'base64'); | ||
const image = await Jimp.read(imageBuffer); | ||
const { width, height } = image.bitmap; | ||
if (!width || !height) { | ||
throw Error('Image processing failed because width or height is undefined'); | ||
} | ||
// Create svg overlay | ||
const svgOverlay = await createSvgOverlay( | ||
elementsPositionInfo, | ||
width, | ||
height, | ||
); | ||
return await Jimp.read(imageBuffer) | ||
.then(async (image: Jimp) => { | ||
const svgImage = await Jimp.read(svgOverlay); | ||
return image.composite(svgImage, 0, 0, { | ||
mode: Jimp.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1, | ||
}); | ||
}) | ||
.then((compositeImage: Jimp) => { | ||
return compositeImage.getBufferAsync(Jimp.MIME_PNG); | ||
}) | ||
.then((buffer: Buffer) => { | ||
return buffer.toString('base64'); | ||
}) | ||
.catch((error: unknown) => { | ||
throw error; | ||
}); | ||
}; | ||
export const processImageElementInfo = async (options: { | ||
@@ -120,67 +182,20 @@ inputImgBase64: string; | ||
const imageBuffer = Buffer.from(base64Image, 'base64'); | ||
const image = await Jimp.read(imageBuffer); | ||
const { width, height } = image.bitmap; | ||
const [ | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64, | ||
] = await Promise.all([ | ||
compositeElementInfoImg({ | ||
inputImgBase64: options.inputImgBase64, | ||
elementsPositionInfo: options.elementsPositionInfo, | ||
}), | ||
compositeElementInfoImg({ | ||
inputImgBase64: options.inputImgBase64, | ||
elementsPositionInfo: options.elementsPositionInfoWithoutText, | ||
}), | ||
]); | ||
if (width && height) { | ||
// Create svg overlay | ||
const svgOverlay = await createSvgOverlay( | ||
options.elementsPositionInfo, | ||
width, | ||
height, | ||
); | ||
const svgOverlayWithoutText = await createSvgOverlay( | ||
options.elementsPositionInfoWithoutText, | ||
width, | ||
height, | ||
); | ||
// Composite picture | ||
const compositeElementInfoImgBase64 = await Jimp.read(imageBuffer) | ||
.then(async (image: Jimp) => { | ||
const svgImage = await Jimp.read(svgOverlay); | ||
return image.composite(svgImage, 0, 0, { | ||
mode: Jimp.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1, | ||
}); | ||
}) | ||
.then((compositeImage: Jimp) => { | ||
return compositeImage.getBufferAsync(Jimp.MIME_PNG); | ||
}) | ||
.then((buffer: Buffer) => { | ||
return buffer.toString('base64'); | ||
}) | ||
.catch((error: unknown) => { | ||
throw error; | ||
}); | ||
// Composite picture withoutText | ||
const compositeElementInfoImgWithoutTextBase64 = await Jimp.read( | ||
imageBuffer, | ||
) | ||
.then(async (image: Jimp) => { | ||
const svgImage = await Jimp.read(svgOverlayWithoutText); | ||
return image.composite(svgImage, 0, 0, { | ||
mode: Jimp.BLEND_SOURCE_OVER, | ||
opacitySource: 1, | ||
opacityDest: 1, | ||
}); | ||
}) | ||
.then((compositeImage: Jimp) => { | ||
return compositeImage.getBufferAsync(Jimp.MIME_PNG); | ||
}) | ||
.then((buffer: Buffer) => { | ||
return buffer.toString('base64'); | ||
}) | ||
.catch((error: unknown) => { | ||
throw error; | ||
}); | ||
return { | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64, | ||
}; | ||
} | ||
throw Error('Image processing failed because width or height is undefined'); | ||
return { | ||
compositeElementInfoImgBase64, | ||
compositeElementInfoImgWithoutTextBase64, | ||
}; | ||
}; |
@@ -1,3 +0,8 @@ | ||
export { imageInfo, imageInfoOfBase64, base64Encoded } from './info'; | ||
export { | ||
imageInfo, | ||
imageInfoOfBase64, | ||
base64Encoded, | ||
base64ToPngFormat, | ||
} from './info'; | ||
export { | ||
trimImage, | ||
@@ -9,2 +14,2 @@ calculateNewDimensions, | ||
} from './transform'; | ||
export { processImageElementInfo } from './box-select'; | ||
export { processImageElementInfo, compositeElementInfoImg } from './box-select'; |
@@ -72,1 +72,5 @@ import assert from 'node:assert'; | ||
} | ||
export function base64ToPngFormat(base64: string) { | ||
return `data:image/png;base64,${base64}`; | ||
} |
54870
1445