feat: refactored PhotonImage API to instance methods with simplified naming

- Refactored PhotonImage API from standalone functions to instance methods with simplified naming conventions.
- Renamed PhotonImage.new_from_byteslice() to parse() for a simpler, more intuitive factory method API.
- Converted PhotonImage.get_width() and get_height() methods to width and height getter properties.
- Consolidated four separate encoding methods (getBytes, getBytesJpeg, getBytesWebp, getBytesGif) into a single encode(format, quality) method.
- Moved resize() from a standalone function to a PhotonImage instance method.
- Added ImageFormat enum to specify encoding formats (PNG, JPEG, WEBP, GIF) in the encode method.
- Removed manual resource management via free() and Symbol.dispose, simplifying PhotonImage lifecycle.
This commit is contained in:
can1357
2026-02-01 15:20:19 +01:00
parent df1a8bfe02
commit e042823697
8 changed files with 116 additions and 229 deletions
@@ -1,4 +1,5 @@
import { PhotonImage } from "@oh-my-pi/pi-natives";
import { ImageFormat } from "@oh-my-pi/pi-natives/native";
/**
* Convert image to PNG format for terminal display.
@@ -14,8 +15,8 @@ export async function convertToPng(
}
try {
using image = await PhotonImage.new_from_byteslice(new Uint8Array(Buffer.from(base64Data, "base64")));
const pngBuffer = await image.get_bytes();
const image = await PhotonImage.parse(new Uint8Array(Buffer.from(base64Data, "base64")));
const pngBuffer = await image.encode(ImageFormat.PNG, 100);
return {
data: Buffer.from(pngBuffer).toString("base64"),
mimeType: "image/png",
@@ -1,5 +1,6 @@
import type { ImageContent } from "@oh-my-pi/pi-ai";
import { PhotonImage, resize, SamplingFilter } from "@oh-my-pi/pi-natives";
import { PhotonImage, SamplingFilter } from "@oh-my-pi/pi-natives";
import { ImageFormat } from "@oh-my-pi/pi-natives/native";
export interface ImageResizeOptions {
maxWidth?: number; // Default: 2000
@@ -54,10 +55,10 @@ export async function resizeImage(img: ImageContent, options?: ImageResizeOption
const inputBuffer = Buffer.from(img.data, "base64");
try {
using image = await PhotonImage.new_from_byteslice(new Uint8Array(inputBuffer));
const image = await PhotonImage.parse(inputBuffer);
const originalWidth = image.get_width();
const originalHeight = image.get_height();
const originalWidth = image.width;
const originalHeight = image.height;
const format = img.mimeType?.split("/")[1] ?? "png";
// Check if already within all limits (dimensions AND size)
@@ -91,11 +92,14 @@ export async function resizeImage(img: ImageContent, options?: ImageResizeOption
async function tryBothFormats(
width: number,
height: number,
jpegQuality: number,
quality: number,
): Promise<{ buffer: Uint8Array; mimeType: string }> {
using resized = await resize(image!, width, height, SamplingFilter.Lanczos3);
const resized = await image.resize(width, height, SamplingFilter.Lanczos3);
const [pngBuffer, jpegBuffer] = await Promise.all([resized.get_bytes(), resized.get_bytes_jpeg(jpegQuality)]);
const [pngBuffer, jpegBuffer] = await Promise.all([
resized.encode(ImageFormat.PNG, quality),
resized.encode(ImageFormat.JPEG, quality),
]);
return pickSmaller(
{ buffer: pngBuffer, mimeType: "image/png" },