@xuda.io/ai_module 1.1.4524 → 1.1.4526

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.mjs +94 -0
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -6998,3 +6998,97 @@ const get_chat_picture_cache = async function (uid, docType, name) {
6998
6998
 
6999
6999
  return null;
7000
7000
  };
7001
+
7002
+ const save_drive_file_to_disk = async function (drive_file) {
7003
+ async function hasTransparentBackground(filePath) {
7004
+ const image = sharp(filePath);
7005
+ const metadata = await image.metadata();
7006
+
7007
+ // If the image doesn't have an alpha channel at all → no transparency possible
7008
+ if (!metadata.hasAlpha) {
7009
+ return false;
7010
+ }
7011
+
7012
+ // For images with alpha channel, check if any pixel actually has alpha < 255
7013
+ const { data, info } = await image.raw().toBuffer({ resolveWithObject: true });
7014
+
7015
+ // Determine position of alpha channel based on number of channels
7016
+ const channels = info.channels; // 2 (grayscale+alpha), 4 (RGBA), etc.
7017
+ const alphaOffset = channels === 2 ? 1 : channels === 4 ? 3 : -1;
7018
+
7019
+ if (alphaOffset === -1) {
7020
+ // Unusual channel count – be conservative and assume it might have transparency
7021
+ return true;
7022
+ }
7023
+
7024
+ for (let i = alphaOffset; i < data.length; i += channels) {
7025
+ if (data[i] < 255) {
7026
+ return true; // Found at least one transparent/semi-transparent pixel
7027
+ }
7028
+ }
7029
+
7030
+ return false; // Has alpha channel but all pixels are fully opaque
7031
+ }
7032
+
7033
+ async function imageToPngBlob(filePath) {
7034
+ const ext = path.extname(filePath).toLowerCase();
7035
+
7036
+ let buffer;
7037
+
7038
+ let is_transparent = false;
7039
+ if (ext === '.png') {
7040
+ buffer = await fs.promises.readFile(filePath);
7041
+ is_transparent = await hasTransparentBackground(filePath);
7042
+ } else {
7043
+ console.log(`Converting ${path.basename(filePath)} to PNG...`);
7044
+ buffer = await sharp(filePath).png({ quality: 100, compressionLevel: 9, force: true }).toBuffer();
7045
+ }
7046
+
7047
+ // Create a Blob with correct MIME type
7048
+
7049
+ return { is_transparent, image_blob: new Blob([buffer], { type: 'image/png' }) };
7050
+ }
7051
+ // try {
7052
+ if (!drive_file.file_url) {
7053
+ throw new Error('No URL provided in request');
7054
+ }
7055
+
7056
+ // 3. Download the image to a Buffer
7057
+ const res = await fetch(drive_file.file_url);
7058
+ if (!res.ok) {
7059
+ throw new Error(`Failed to fetch image URL: ${res.status} ${res.statusText}`);
7060
+ }
7061
+
7062
+ const arrayBuffer = await res.arrayBuffer();
7063
+ const imageBuffer = Buffer.from(arrayBuffer);
7064
+
7065
+ const tempDir = os.tmpdir();
7066
+ const uniqueId = Date.now() + '_' + Math.random().toString(36).substring(7);
7067
+
7068
+ const inputExt = path.extname(url) || '.jpg';
7069
+ const tempInputPath = path.join(tempDir, `input_${uniqueId}${inputExt}`);
7070
+ // const tempOutputPath = path.join(tempDir, `output_${uniqueId}.png`); // Output is always PNG (transparent)
7071
+
7072
+ // 5. Write the downloaded image to disk
7073
+ fs.writeFileSync(tempInputPath, imageBuffer);
7074
+ /////////////////////////////////
7075
+
7076
+ const imageFiles = [tempInputPath];
7077
+
7078
+ const images = await Promise.all(
7079
+ imageFiles.map(async (filePath) => {
7080
+ const img_ret = await imageToPngBlob(filePath);
7081
+ const blob = img_ret.image_blob;
7082
+
7083
+ // OpenAI expects a filename for logging/debugging
7084
+ const filename = path.basename(filePath, path.extname(filePath)) + '.png';
7085
+ blob.name = filename; // Optional but helpful
7086
+ // @ts-ignore – name is allowed in Node 20+
7087
+ blob.lastModified = Date.now();
7088
+
7089
+ return { is_transparent: img_ret.is_transparent, image_blob: blob };
7090
+ }),
7091
+ );
7092
+
7093
+ return images[0];
7094
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xuda.io/ai_module",
3
- "version": "1.1.4524",
3
+ "version": "1.1.4526",
4
4
  "description": "Xuda AI Module",
5
5
  "main": "index.mjs",
6
6
  "type": "module",