fix: background zoom mismatch between cached and real-time calculated result
This commit is contained in:
parent
5afdaec8a0
commit
6d9c826b1d
@ -1,20 +1,29 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { processImage } from '$lib/graphics';
|
import { processImage } from '$lib/graphics';
|
||||||
import localforage from 'localforage';
|
import blobToImageData from '$lib/graphics/blob2imageData';
|
||||||
// Initialize IndexedDB
|
import imageDataToBlob from '$lib/graphics/imageData2blob';
|
||||||
localforage.config({
|
import localforage from '$lib/storage';
|
||||||
driver: localforage.INDEXEDDB,
|
|
||||||
name: 'audioDB'
|
|
||||||
});
|
|
||||||
|
|
||||||
export let coverId: string;
|
export let coverId: string;
|
||||||
let canvas: HTMLCanvasElement;
|
let canvas: HTMLCanvasElement;
|
||||||
localforage.getItem(`${coverId}-cover`, function (err, file) {
|
|
||||||
console.log(file);
|
let flag = false;
|
||||||
console.log(err);
|
localforage.getItem(`${coverId}-cover-cache`, function (err, file) {
|
||||||
if (file) {
|
if (file) {
|
||||||
const path = URL.createObjectURL(file as File);
|
const ctx = canvas.getContext('2d');
|
||||||
processImage(16, 4, 96, path, canvas);
|
blobToImageData(file as Blob).then((imageData) => {
|
||||||
|
console.log(imageData);
|
||||||
|
ctx?.putImageData(imageData,0,0);
|
||||||
|
})
|
||||||
|
|
||||||
|
} else {
|
||||||
|
localforage.getItem(`${coverId}-cover`, function (err, file) {
|
||||||
|
if (file) {
|
||||||
|
const path = URL.createObjectURL(file as File);
|
||||||
|
processImage(16, 3, 96, path, canvas, (resultImageData: ImageData) => {
|
||||||
|
localforage.setItem(`${coverId}-cover-cache`, imageDataToBlob(resultImageData));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -37,8 +46,8 @@
|
|||||||
}
|
}
|
||||||
canvas {
|
canvas {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 110%;
|
|
||||||
height: 110%;
|
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
17
src/lib/graphics/blob2imageData.ts
Normal file
17
src/lib/graphics/blob2imageData.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export default function blobToImageData(blob: Blob): Promise<ImageData> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = (event) => {
|
||||||
|
const arrayBuffer = event.target?.result as ArrayBuffer;
|
||||||
|
const dataView = new DataView(arrayBuffer);
|
||||||
|
const width = dataView.getUint32(0, true); // Read width from little-endian bytes
|
||||||
|
const height = dataView.getUint32(4, true); // Read height from little-endian bytes
|
||||||
|
const byteArray = new Uint8ClampedArray(arrayBuffer, 8); // Skip the header
|
||||||
|
resolve(new ImageData(byteArray, width, height));
|
||||||
|
};
|
||||||
|
reader.onerror = () => {
|
||||||
|
reject(new Error("Failed to read Blob as ArrayBuffer"));
|
||||||
|
};
|
||||||
|
reader.readAsArrayBuffer(blob);
|
||||||
|
});
|
||||||
|
}
|
11
src/lib/graphics/imageData2blob.ts
Normal file
11
src/lib/graphics/imageData2blob.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export default function imageDataToBlob(imageData: ImageData): Blob {
|
||||||
|
const width = imageData.width;
|
||||||
|
const height = imageData.height;
|
||||||
|
const data = new Uint8ClampedArray(imageData.data);
|
||||||
|
const header = new Uint8Array(8); // 4 bytes for width, 4 bytes for height
|
||||||
|
const dataView = new DataView(header.buffer);
|
||||||
|
dataView.setUint32(0, width, true); // Store width in little-endian
|
||||||
|
dataView.setUint32(4, height, true); // Store height in little-endian
|
||||||
|
const blob = new Blob([header, data], { type: 'image/png' });
|
||||||
|
return blob;
|
||||||
|
}
|
@ -1,46 +1,34 @@
|
|||||||
import { gaussianBlurHorizontal, gaussianBlurVertical, applyFilter } from "./utils";
|
import { gaussianBlurHorizontal, gaussianBlurVertical, applyFilter } from './utils';
|
||||||
|
|
||||||
export async function processImage(blockSize: number, resolutionFactor:number, radius:number, path: string, canvas: HTMLCanvasElement) {
|
export function processImage(
|
||||||
const ctx = canvas.getContext("2d")!;
|
blockSize: number,
|
||||||
|
resolutionFactor: number,
|
||||||
|
radius: number,
|
||||||
|
path: string,
|
||||||
|
canvas: HTMLCanvasElement,
|
||||||
|
callback: (resultImageData: ImageData) => void
|
||||||
|
) {
|
||||||
|
const ctx = canvas.getContext('2d')!;
|
||||||
|
|
||||||
const image = new Image();
|
const image = new Image();
|
||||||
image.src = path; // Replace with your image path
|
image.src = path; // Replace with your image path
|
||||||
|
|
||||||
image.onload = function () {
|
image.onload = function () {
|
||||||
// Resize image to 1/9 of the original resolution
|
// Resize image to 1/9 of the original resolution
|
||||||
|
const width = image.width;
|
||||||
|
const height = image.height;
|
||||||
const resizedWidth = image.width / resolutionFactor;
|
const resizedWidth = image.width / resolutionFactor;
|
||||||
const resizedHeight = image.height / resolutionFactor;
|
const resizedHeight = image.height / resolutionFactor;
|
||||||
|
|
||||||
const num_blocks_x = Math.floor(resizedWidth / blockSize);
|
|
||||||
const num_blocks_y = Math.floor(resizedHeight / blockSize);
|
|
||||||
|
|
||||||
canvas.width = resizedWidth;
|
canvas.width = resizedWidth;
|
||||||
canvas.height = resizedHeight;
|
canvas.height = resizedHeight;
|
||||||
|
const block = document.createElement('canvas');
|
||||||
for (let i = 0; i < num_blocks_y; i++) {
|
const blockCtx = block.getContext('2d')!;
|
||||||
for (let j = 0; j < num_blocks_x; j++) {
|
block.width = image.width;
|
||||||
const block = document.createElement("canvas");
|
block.height = image.height;
|
||||||
block.width = blockSize;
|
blockCtx.drawImage(image, 0, 0, width, height, 0, 0, resizedWidth, resizedHeight);
|
||||||
block.height = blockSize;
|
applyFilter(block);
|
||||||
|
ctx.drawImage(block, 0, 0);
|
||||||
const blockCtx = block.getContext("2d")!;
|
|
||||||
blockCtx.drawImage(
|
|
||||||
image,
|
|
||||||
j * blockSize * resolutionFactor,
|
|
||||||
i * blockSize * resolutionFactor,
|
|
||||||
blockSize * resolutionFactor,
|
|
||||||
blockSize * resolutionFactor,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
blockSize,
|
|
||||||
blockSize
|
|
||||||
);
|
|
||||||
|
|
||||||
applyFilter(block);
|
|
||||||
|
|
||||||
ctx.drawImage(block, j * blockSize, i * blockSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Horizontal Gaussian blur
|
// Horizontal Gaussian blur
|
||||||
const imageDataHorizontal = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
const imageDataHorizontal = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
@ -50,6 +38,7 @@ export async function processImage(blockSize: number, resolutionFactor:number, r
|
|||||||
const imageDataVertical = blurredImageDataHorizontal;
|
const imageDataVertical = blurredImageDataHorizontal;
|
||||||
const blurredImageData = gaussianBlurVertical(imageDataVertical, radius);
|
const blurredImageData = gaussianBlurVertical(imageDataVertical, radius);
|
||||||
|
|
||||||
ctx.putImageData(blurredImageData, 0, 0);
|
ctx.putImageData(blurredImageData, 0, 0, 0, 0, width, height);
|
||||||
|
callback(blurredImageData);
|
||||||
};
|
};
|
||||||
}
|
}
|
8
src/lib/storage.ts
Normal file
8
src/lib/storage.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import localforage from "localforage";
|
||||||
|
|
||||||
|
localforage.config({
|
||||||
|
driver: localforage.INDEXEDDB,
|
||||||
|
name: 'audioDB'
|
||||||
|
});
|
||||||
|
|
||||||
|
export default localforage;
|
@ -15,7 +15,6 @@
|
|||||||
// Handle audio input change
|
// Handle audio input change
|
||||||
audioInput.addEventListener('change', function (e: any) {
|
audioInput.addEventListener('change', function (e: any) {
|
||||||
const file: File = e.target.files[0];
|
const file: File = e.target.files[0];
|
||||||
console.log(file.size);
|
|
||||||
if (file) {
|
if (file) {
|
||||||
localforage.setItem(audioId + '-file', file);
|
localforage.setItem(audioId + '-file', file);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user