Initial commit

This commit is contained in:
meusinfirmary
2025-04-22 14:31:37 +07:00
commit b7e852126c
115 changed files with 23188 additions and 0 deletions

140
library/LibImgGeotagging.js Normal file
View File

@ -0,0 +1,140 @@
const fs = require('fs');
const path = require("path");
const moment = require('moment');
const Jimp = require("jimp");
/**
* download ttf font => https://www.fontspace.com/search?q=open%20sans
* load custom font on jimp => https://github.com/oliver-moran/jimp/issues/375
* convert ttf to (fnt,png) => https://github.com/oliver-moran/jimp/issues/1002 => https://ttf2fnt.com/
* neon color palette => https://icolorpalette.com/color/neon-green
* reference => https://libgdx.com/wiki/graphics/2d/fonts/bitmap-fonts
*/
const FONT_OPEN_SANS_NEON_100 = path.resolve(__dirname, '../files/public/OpenSans-B9K8.ttf_neon_100/neon_100.fnt');
const FONT_OPEN_SANS_NEON_64 = path.resolve(__dirname, '../files/public/OpenSans-B9K8.ttf_neon_64/neon_64.fnt');
const FONT_OPEN_SANS_NEON_32 = path.resolve(__dirname, '../files/public/OpenSans-B9K8.ttf_neon_32/neon_32.fnt');
const FONT_OPEN_SANS_NEON_16 = path.resolve(__dirname, '../files/public/OpenSans-B9K8.ttf_neon_16/neon_16.fnt');
class LibImgGeotagging {
static create(tempFileName = '', tempFileNamePath = '', photo = 'base64', { fulladdress, lat, lng, photo_at }) {
return new Promise(async (resolve, reject) => {
try {
const JimpLoadedFile = await Jimp.read(Buffer.from(photo.replace(/^data:(image|application)\/(png|jpg|jpeg);base64,/, ''), 'base64'));
JimpLoadedFile.quality(60);
fulladdress = (fulladdress) ? decodeURIComponent(fulladdress) : null;
let theAddr = fulladdress || '';
let text = moment.unix(photo_at).format('DD MMMM YYYY HH:mm:ss') + ' WIB' + ' ' + lat + ',' + lng + ' ' + theAddr;
let startX = 10;
let startY = 10;
// example 00
// const JimpLoadFont = await Jimp.loadFont(Jimp.FONT_SANS_64_WHITE);
// await JimpLoadedFile
// // .print(JimpLoadFont, startX, JimpLoadedFile.bitmap.height-450, { text }, JimpLoadedFile.bitmap.width)
// .print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * 75 / 100, JimpLoadedFile.bitmap.height)
// // .print(JimpLoadFont, startX, startY, { text: moment.unix(photo_at).format('YYYY-MM-DD HH:mm:ss') + ' WIB', alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width, JimpLoadedFile.bitmap.height)
// // .print(JimpLoadFont, startX, startY, { text: '' + lat + ',' + lng, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width, JimpLoadedFile.bitmap.height)
// // .print(JimpLoadFont, startX, startY, { text: `${theAddr}`, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width, JimpLoadedFile.bitmap.height)
// .writeAsync(tempFileNamePath);
// example with set background with opacity 01
// const imgBg = Buffer.from(fs.readFileSync(path.resolve(__dirname, '../files/public/img_white_bg.png'))).toString('base64');
// const JimpImgBg = await Jimp.read(Buffer.from(imgBg.replace(/^data:(image|application)\/(png|jpg|jpeg);base64,/, ''), 'base64'));
// const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(Jimp.FONT_SANS_32_BLACK) : await Jimp.loadFont(Jimp.FONT_SANS_32_BLACK);
// await JimpLoadedFile
// .composite(JimpImgBg, 0, JimpLoadedFile.bitmap.height-200, { mode: Jimp.BLEND_SOURCE_OVER, opacitySource: 0.5, opacityDest: 1 })
// .print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
// .writeAsync(tempFileNamePath);
// write geotagging based on size
// https://www.pixel.web.id/ukuran-foto-sesuai-standar/
// font color => https://www.fontspace.com/search?q=open%20sans
/**
* kalo height <= 600px maka metode maka jadikan satu baru menggunakan alignmentX dan Y
* kalo height > 600px maka metode print pecah jadi 3 baris dan pake minus(-) di startY, misal -300 -200 -100
*/
console.log('image width => ', JimpLoadedFile.bitmap.width, ' || ', 'image height => ', JimpLoadedFile.bitmap.height);
const percent = (JimpLoadedFile.bitmap.height > 1000) ? 75 : 50;
if (JimpLoadedFile.bitmap.width > 3000) {
startY = -10;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_100) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_64);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 2400) {
startY = -10;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_64) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_64);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 2100) {
startY = -10;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_64) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_64);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 1800) {
// done testing
startY = -10;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_64) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_32);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 1650) {
startY = -10;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_32) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_32);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 1500) {
startY = -10;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_32) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_32);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 1200) {
startY = -10;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_32) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_32);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 900) {
// done testing
startY = -10;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_32) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_32);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 750) {
// done testing
startX = 8;
startY = -8;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_32) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_16);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else if (JimpLoadedFile.bitmap.width > 400) {
startX = 5;
startY = -5;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_16) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_16);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
} else {
startX = 5;
startY = -5;
const JimpLoadFont = (JimpLoadedFile.bitmap.height > 1000) ? await Jimp.loadFont(FONT_OPEN_SANS_NEON_16) : await Jimp.loadFont(FONT_OPEN_SANS_NEON_16);
await JimpLoadedFile
.print(JimpLoadFont, startX, startY, { text, alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT, alignmentY: Jimp.VERTICAL_ALIGN_BOTTOM }, JimpLoadedFile.bitmap.width * percent / 100, JimpLoadedFile.bitmap.height)
.writeAsync(tempFileNamePath);
}
resolve({type: 'sc'});
} catch (e) {
reject({type: 'err', e});
}
});
}
}
module.exports = LibImgGeotagging;