Optimize data loading for attachments/thumbnail generation

This commit is contained in:
N-Pex 2025-07-17 10:30:14 +02:00
parent 1f13e462b6
commit 7b4b35762a
3 changed files with 53 additions and 59 deletions

View file

@ -329,7 +329,6 @@ import roomMembersMixin from "./roomMembersMixin";
import PurgeRoomDialog from "../components/PurgeRoomDialog";
import MessageErrorHandler from "./MessageErrorHandler";
import MessageOperationsChannel from './messages/channel/MessageOperationsChannel.vue';
import { imageSize } from "image-size";
import prettyBytes from "pretty-bytes";
import RoomExport from "./RoomExport.vue";
import EmojiPicker from 'vue3-emoji-picker';

View file

@ -8,14 +8,8 @@ import {
} from "./eventAttachment";
import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
import { Counter, ModeOfOperation } from "aes-js";
import {
Attachment,
AttachmentBatch,
AttachmentSendInfo,
AttachmentThumbnail,
} from "./attachment";
import { Attachment, AttachmentBatch, AttachmentSendInfo, AttachmentThumbnail } from "./attachment";
import proofmode from "../plugins/proofmode";
import imageSize from "image-size";
import imageResize from "image-resize";
import { computed, Reactive, reactive, ref, Ref, shallowReactive } from "vue";
import utils, { THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT } from "@/plugins/utils";
@ -64,60 +58,62 @@ export class AttachmentManager {
const file = attachment.file;
if (file.type.startsWith("image/")) {
attachment.proof = await proofmode.proofCheckFile(file);
let url = URL.createObjectURL(file);
attachment.src = url;
if (attachment.src) {
try {
let img = new Image();
img.src = url;
attachment.dimensions = await new Promise((response) => {
img.onload = (event) => {
console.log("height: " + img.height);
console.log("width: " + img.width);
response({ width: img.width, height: img.height });
};
img.onerror = (event) => {
response(undefined);
};
});
var reader = new FileReader();
await new Promise((resolve) => {
reader.onload = (evt) => {
attachment.src = (evt.target?.result as string) ?? undefined;
if (attachment.src) {
try {
const buffer = Uint8Array.from(window.atob(attachment.src.replace(/^data[^,]+,/, "")), (v) =>
v.charCodeAt(0)
);
attachment.dimensions = imageSize(buffer);
// Need to resize?
const w = attachment.dimensions.width;
const h = attachment.dimensions.height;
if (w > 640 || h > 640) {
var aspect = w / h;
var newWidth = parseInt((w > h ? 640 : 640 * aspect).toFixed());
var newHeight = parseInt((w > h ? 640 / aspect : 640).toFixed());
imageResize(attachment.src, {
format: "webp",
// Need to resize?
const w = attachment.dimensions?.width ?? 0;
const h = attachment.dimensions?.height ?? 0;
if (w > 640 || h > 640) {
var aspect = w / h;
var newWidth = parseInt((w > h ? 640 : 640 * aspect).toFixed());
var newHeight = parseInt((w > h ? 640 / aspect : 640).toFixed());
imageResize(file, {
format: "webp",
width: newWidth,
height: newHeight,
outputType: "blob",
})
.then((img) => {
attachment.scaledFile = new File([img as BlobPart], file.name, {
type: "image/webp",
lastModified: Date.now(),
});
attachment.scaledDimensions = {
width: newWidth,
height: newHeight,
outputType: "blob",
})
.then((img) => {
attachment.scaledFile = new File([img as BlobPart], file.name, {
type: "image/webp",
lastModified: Date.now(),
});
attachment.scaledDimensions = {
width: newWidth,
height: newHeight,
};
};
// Use scaled version if the image does not contain C2PA
attachment.useScaled =
attachment.scaledFile !== undefined &&
(attachment.proof === undefined ||
attachment.proof.integrity === undefined ||
attachment.proof.integrity.c2pa === undefined);
})
.catch((err) => {
console.error("Resize failed:", err);
});
}
} catch (error) {
console.error("Failed to get image dimensions: " + error);
}
// Default to scaled version if the image does not contain Content Credentials
//
attachment.useScaled =
attachment.scaledFile !== undefined &&
(attachment.proof === undefined ||
attachment.proof.integrity === undefined ||
attachment.proof.integrity.c2pa === undefined);
})
.catch((err) => {
console.error("Resize failed:", err);
});
}
resolve(true);
};
reader.readAsDataURL(file);
});
} catch (error) {
console.error("Failed to get image dimensions: " + error);
}
}
} else if (file.type.startsWith("video/")) {
let url = URL.createObjectURL(file);
const thumb: AttachmentThumbnail | undefined = await new Promise((resolve) => {
@ -146,8 +142,6 @@ export class AttachmentManager {
const ctx = canvas.getContext("2d");
if (ctx) {
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, canvas.width, canvas.height);
// ctx.fillStyle = "white";
// ctx.fillText("Thumbnail", 10, 10);
}
canvas.toBlob((b) => {
b?.arrayBuffer().then((data) => {

View file

@ -50,6 +50,7 @@ export type C2PAData = {
}
export type Proof = {
data?: any;
name?: string;
json?: string;
integrity?: { pgp?: any; c2pa?: any; exif?: {[key: string]: string | Object}; opentimestamps?: any };