This commit is contained in:
Manav Rathi
2025-02-27 11:59:34 +05:30
parent 7fc03a71e7
commit ee201ff24b
2 changed files with 41 additions and 12 deletions

View File

@@ -64,6 +64,14 @@ export type ItemData = PhotoSwipeSlideData & {
* portion of the live photo.
*/
imageURL?: string;
/**
* The original image associated with the file, as a Blob.
*
* - For images, this will be the original image itself.
* - For live photos, this will be the image component of the live photo.
* - For videos, this will be not be present.
*/
originalImageBlob?: Blob;
/**
* The renderable object URL of the video associated with the file.
*
@@ -283,8 +291,9 @@ const enqueueUpdates = async (file: EnteFile) => {
const sourceURLs =
await downloadManager.renderableSourceURLs(file);
const imageURL = ensureString(sourceURLs.url);
const originalImageBlob = sourceURLs.originalImageBlob!;
const itemData = await withDimensions(imageURL);
update({ ...itemData, imageURL });
update({ ...itemData, imageURL, originalImageBlob });
break;
}
@@ -301,8 +310,16 @@ const enqueueUpdates = async (file: EnteFile) => {
await downloadManager.renderableSourceURLs(file);
const livePhotoSourceURLs =
sourceURLs.url as LivePhotoSourceURL;
const imageURL = await livePhotoSourceURLs.image();
const imageData = await withDimensions(ensureString(imageURL));
const imageURL = ensureString(
await livePhotoSourceURLs.image(),
);
const originalImageBlob =
(await livePhotoSourceURLs.originalImageBlob())!;
const imageData = {
...(await withDimensions(imageURL)),
imageURL,
originalImageBlob,
};
update(imageData);
const videoURL = await livePhotoSourceURLs.video();
update({ ...imageData, videoURL });
@@ -390,7 +407,7 @@ export const fileInfoExifForFile = (
*
* This function is expected to be called when an item is loaded as PhotoSwipe
* content. It can be safely called multiple times - it will ignore calls until
* the item has an associated {@link imageURL}, and it will also ignore calls
* the item has an associated {@link originalImageBlob}, and it will also ignore calls
* that are made after exif data has already been extracted.
*
* If required, it will extract the exif data from the file, massage it to a
@@ -401,7 +418,7 @@ export const fileInfoExifForFile = (
* See also {@link forgetExifForItemData}.
*/
export const updateFileInfoExifIfNeeded = async (itemData: ItemData) => {
const { fileID, fileType, imageURL } = itemData;
const { fileID, fileType, originalImageBlob } = itemData;
// We already have it available.
if (_state.fileInfoExifByFileID.has(fileID)) return;
@@ -418,11 +435,10 @@ export const updateFileInfoExifIfNeeded = async (itemData: ItemData) => {
}
// This is not a video, but the original image is not available yet.
if (!imageURL) return;
if (!originalImageBlob) return;
try {
const blob = await (await fetch(imageURL)).blob();
const file = new File([blob], "");
const file = new File([originalImageBlob], "");
const tags = await extractRawExif(file);
const parsed = parseExif(tags);
return updateNotifyAndReturn({ tags, parsed });

View File

@@ -26,6 +26,7 @@ import { decodeLivePhoto } from "@/media/live-photo";
export interface LivePhotoSourceURL {
image: () => Promise<string | undefined>;
originalImageBlob: () => Promise<Blob | undefined>;
video: () => Promise<string | undefined>;
}
@@ -52,7 +53,7 @@ export interface LoadedLivePhotoSourceURL {
*/
export interface RenderableSourceURLs {
url: string | LivePhotoSourceURL | LoadedLivePhotoSourceURL;
originalImageURL?: string | undefined;
originalImageBlob?: Blob | undefined;
type: "normal" | "livePhoto";
/**
* `true` if there is potential conversion that can still be applied.
@@ -598,7 +599,9 @@ const createRenderableSourceURLs = async (
: undefined;
let url: RenderableSourceURLs["url"] | undefined;
let originalImageURL: RenderableSourceURLs["originalImageURL"] | undefined;
let originalImageBlob:
| RenderableSourceURLs["originalImageBlob"]
| undefined;
let type: RenderableSourceURLs["type"] = "normal";
let mimeType: string | undefined;
let canForceConvert = false;
@@ -609,7 +612,7 @@ const createRenderableSourceURLs = async (
const convertedBlob = await renderableImageBlob(fileBlob, fileName);
const convertedURL = existingOrNewObjectURL(convertedBlob);
url = convertedURL;
originalImageURL = originalFileURL;
originalImageBlob = fileBlob;
mimeType = convertedBlob.type;
break;
}
@@ -646,7 +649,7 @@ const createRenderableSourceURLs = async (
// @ts-ignore
return {
url: url!,
originalImageURL,
originalImageBlob,
type,
mimeType,
canForceConvert,
@@ -671,6 +674,15 @@ async function getRenderableLivePhotoURL(
}
};
const getOriginalImageBlob = async () => {
try {
return new Blob([livePhoto.imageData]);
} catch {
//ignore and return null
return undefined;
}
};
const getRenderableLivePhotoVideoURL = async () => {
try {
const videoBlob = new Blob([livePhoto.videoData]);
@@ -689,6 +701,7 @@ async function getRenderableLivePhotoURL(
return {
image: getRenderableLivePhotoImageURL,
originalImageBlob: getOriginalImageBlob,
video: getRenderableLivePhotoVideoURL,
};
}