diff --git a/.prettierrc b/.prettierrc
index 9573023..f98a0aa 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -1,5 +1,6 @@
{
- "useTabs": true,
+ "useTabs": false,
+ "tabWidth": 4,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
diff --git a/jsconfig.json b/jsconfig.json
index fc93cbd..f28e9d5 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -2,7 +2,7 @@
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
- "checkJs": true,
+ "checkJs": false,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
diff --git a/package.json b/package.json
index 06b7ded..b3b614a 100644
--- a/package.json
+++ b/package.json
@@ -28,5 +28,8 @@
"vite": "^5.0.3",
"vitest": "^1.2.0"
},
- "type": "module"
+ "type": "module",
+ "dependencies": {
+ "localforage": "^1.10.0"
+ }
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 234364f..0f0e0ed 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4,6 +4,11 @@ settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
+dependencies:
+ localforage:
+ specifier: ^1.10.0
+ version: 1.10.0
+
devDependencies:
'@sveltejs/adapter-auto':
specifier: ^3.0.0
@@ -1271,6 +1276,10 @@ packages:
engines: {node: '>= 4'}
dev: true
+ /immediate@3.0.6:
+ resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
+ dev: false
+
/import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
@@ -1389,6 +1398,12 @@ packages:
type-check: 0.4.0
dev: true
+ /lie@3.1.1:
+ resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==}
+ dependencies:
+ immediate: 3.0.6
+ dev: false
+
/lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'}
@@ -1402,6 +1417,12 @@ packages:
pkg-types: 1.1.0
dev: true
+ /localforage@1.10.0:
+ resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
+ dependencies:
+ lie: 3.1.1
+ dev: false
+
/locate-character@3.0.0:
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
dev: true
diff --git a/src/components/background.svelte b/src/components/background.svelte
new file mode 100644
index 0000000..9b59aeb
--- /dev/null
+++ b/src/components/background.svelte
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
diff --git a/src/lib/graphics/index.ts b/src/lib/graphics/index.ts
new file mode 100644
index 0000000..148b4df
--- /dev/null
+++ b/src/lib/graphics/index.ts
@@ -0,0 +1,55 @@
+import { gaussianBlurHorizontal, gaussianBlurVertical, applyFilter } from "./utils";
+
+export async function processImage(blockSize: number, resolutionFactor:number, radius:number, path: string, canvas: HTMLCanvasElement) {
+ const ctx = canvas.getContext("2d")!;
+
+ const image = new Image();
+ image.src = path; // Replace with your image path
+
+ image.onload = function () {
+ // Resize image to 1/9 of the original resolution
+ const resizedWidth = image.width / 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.height = resizedHeight;
+
+ for (let i = 0; i < num_blocks_y; i++) {
+ for (let j = 0; j < num_blocks_x; j++) {
+ const block = document.createElement("canvas");
+ block.width = blockSize;
+ block.height = blockSize;
+
+ 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
+ const imageDataHorizontal = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ const blurredImageDataHorizontal = gaussianBlurHorizontal(imageDataHorizontal, radius);
+
+ // Vertical Gaussian blur
+ const imageDataVertical = blurredImageDataHorizontal;
+ const blurredImageData = gaussianBlurVertical(imageDataVertical, radius);
+
+ ctx.putImageData(blurredImageData, 0, 0);
+ };
+}
\ No newline at end of file
diff --git a/src/lib/graphics/utils.js b/src/lib/graphics/utils.js
new file mode 100644
index 0000000..51d3b64
--- /dev/null
+++ b/src/lib/graphics/utils.js
@@ -0,0 +1,191 @@
+// Function to apply filter to the block
+export function applyFilter(block) {
+ let imageData = block.getContext("2d").getImageData(0, 0, block.width, block.height);
+ let data = imageData.data;
+
+ for (let i = 0; i < data.length; i += 4) {
+ let hsv = rgbToHsv(data[i], data[i + 1], data[i + 2]);
+
+ // Mainly adjust saturation and value channels
+ hsv[1] = Math.min(hsv[1] * 1.05 + 30 * Math.log(hsv[1] / 100 + 1), 100);
+ hsv[2] = Math.min(hsv[2] * 1.3 + 40 * Math.log(hsv[2] / 100 + 1), 100);
+
+ let rgb = hsvToRgb(hsv[0], hsv[1], hsv[2]);
+
+ data[i] = rgb[0];
+ data[i + 1] = rgb[1];
+ data[i + 2] = rgb[2];
+ }
+
+ block.getContext("2d").putImageData(imageData, 0, 0);
+}
+
+// Function to perform horizontal Gaussian blur
+export function gaussianBlurHorizontal(imageData, radius) {
+ const width = imageData.width;
+ const height = imageData.height;
+
+ const newData = new Uint8ClampedArray(imageData.data);
+
+ const kernel = generateGaussianKernel(radius);
+
+ for (let y = 0; y < height; y++) {
+ for (let x = 0; x < width; x++) {
+ let r = 0,
+ g = 0,
+ b = 0,
+ a = 0;
+
+ for (let kx = -radius; kx <= radius; kx++) {
+ const pixelX = Math.min(width - 1, Math.max(0, x + kx));
+
+ const kernelValue = kernel[kx + radius];
+
+ const index = (y * width + pixelX) * 4;
+
+ r += imageData.data[index] * kernelValue;
+ g += imageData.data[index + 1] * kernelValue;
+ b += imageData.data[index + 2] * kernelValue;
+ a += imageData.data[index + 3] * kernelValue;
+ }
+
+ const dataIndex = (y * width + x) * 4;
+ newData[dataIndex] = r;
+ newData[dataIndex + 1] = g;
+ newData[dataIndex + 2] = b;
+ newData[dataIndex + 3] = a;
+ }
+ }
+
+ return new ImageData(newData, width, height);
+}
+
+// Function to perform vertical Gaussian blur
+export function gaussianBlurVertical(imageData, radius) {
+ const width = imageData.width;
+ const height = imageData.height;
+
+ const newData = new Uint8ClampedArray(imageData.data);
+
+ const kernel = generateGaussianKernel(radius);
+
+ for (let y = 0; y < height; y++) {
+ for (let x = 0; x < width; x++) {
+ let r = 0,
+ g = 0,
+ b = 0,
+ a = 0;
+
+ for (let ky = -radius; ky <= radius; ky++) {
+ const pixelY = Math.min(height - 1, Math.max(0, y + ky));
+
+ const kernelValue = kernel[ky + radius];
+
+ const index = (pixelY * width + x) * 4;
+
+ r += imageData.data[index] * kernelValue;
+ g += imageData.data[index + 1] * kernelValue;
+ b += imageData.data[index + 2] * kernelValue;
+ a += imageData.data[index + 3] * kernelValue;
+ }
+
+ const dataIndex = (y * width + x) * 4;
+ newData[dataIndex] = r;
+ newData[dataIndex + 1] = g;
+ newData[dataIndex + 2] = b;
+ newData[dataIndex + 3] = a;
+ }
+ }
+
+ return new ImageData(newData, width, height);
+}
+
+// Function to generate Gaussian kernel
+function generateGaussianKernel(radius) {
+ const size = radius * 2 + 1;
+ const kernel = [];
+
+ const sigma = 0.4 * ((radius - 1) * 0.5 - 1) + 0.8;
+
+ for (let i = 0; i < size; i++) {
+ const x = i - radius;
+ const exponent = Math.exp(-(x * x) / (2 * sigma * sigma));
+ kernel[i] = exponent / (Math.sqrt(2 * Math.PI) * sigma);
+ }
+
+ // Normalize the kernel
+ const sum = kernel.reduce((a, b) => a + b, 0);
+ return kernel.map((value) => value / sum);
+}
+
+// Function to convert RGB to HSV
+function rgbToHsv(r, g, b) {
+ (r /= 255), (g /= 255), (b /= 255);
+
+ let max = Math.max(r, g, b),
+ min = Math.min(r, g, b),
+ h,
+ s,
+ v = max;
+
+ let d = max - min;
+ s = max === 0 ? 0 : d / max;
+
+ if (max === min) {
+ h = 0; // achromatic
+ } else {
+ switch (max) {
+ case r:
+ h = (g - b) / d + (g < b ? 6 : 0);
+ break;
+ case g:
+ h = (b - r) / d + 2;
+ break;
+ case b:
+ h = (r - g) / d + 4;
+ break;
+ }
+ h /= 6;
+ }
+
+ return [h * 360, s * 100, v * 100];
+}
+
+// Function to convert HSV to RGB
+function hsvToRgb(h, s, v) {
+ h /= 360;
+ s /= 100;
+ v /= 100;
+
+ let i = Math.floor(h * 6),
+ f = h * 6 - i,
+ p = v * (1 - s),
+ q = v * (1 - f * s),
+ t = v * (1 - (1 - f) * s),
+ r,
+ g,
+ b;
+
+ switch (i % 6) {
+ case 0:
+ (r = v), (g = t), (b = p);
+ break;
+ case 1:
+ (r = q), (g = v), (b = p);
+ break;
+ case 2:
+ (r = p), (g = v), (b = t);
+ break;
+ case 3:
+ (r = p), (g = q), (b = v);
+ break;
+ case 4:
+ (r = t), (g = p), (b = v);
+ break;
+ case 5:
+ (r = v), (g = p), (b = q);
+ break;
+ }
+
+ return [r * 255, g * 255, b * 255];
+}
\ No newline at end of file
diff --git a/src/lib/index.js b/src/lib/index.js
deleted file mode 100644
index 856f2b6..0000000
--- a/src/lib/index.js
+++ /dev/null
@@ -1 +0,0 @@
-// place files you want to import through the `$lib` alias in this folder.
diff --git a/src/routes/+page.server.js b/src/routes/+page.server.js
new file mode 100644
index 0000000..5829b7e
--- /dev/null
+++ b/src/routes/+page.server.js
@@ -0,0 +1 @@
+export const ssr = false;
\ No newline at end of file
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 5982b0a..d846875 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,2 +1,52 @@
-Welcome to SvelteKit
-Visit kit.svelte.dev to read the documentation
+
+
+
+ Select Audio File:
+
+
+
+ Select Cover File:
+
+
+
+
+
\ No newline at end of file
diff --git a/svelte.config.js b/svelte.config.js
index 2ca5922..b9a0894 100644
--- a/svelte.config.js
+++ b/svelte.config.js
@@ -1,4 +1,5 @@
import adapter from '@sveltejs/adapter-auto';
+import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
@@ -7,7 +8,8 @@ const config = {
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter()
- }
+ },
+ preprocess: vitePreprocess()
};
export default config;