パーリンノイズジェネレーター (Pārin noizu jenerēta)

パーリンノイズジェネレーター (Pārin noizu jenerēta)

ログイン • 25 ダウンロード

変更履歴

v1.0

コンテンツ

A image or text to prelin noise image generator Needs scriptable, copy an paste this into a browser then copy text into a scriptable: https://www.icloud.com/attachment/?u=https%3A%2F%2Fcvws.icloud-content.com%2FB%2FAdz9_P-lhgYJ5l5b5IeKtyDW0ieRAc2-NyDfKqpPUUfvwHWaXgFXLJDo%2F%24%7Bf%7D%3Fo%3DAtV50_11fKvwAUVyQ5Td200JtGKsFfX-g4PjieC-c1bC%26v%3D1%26x%3D3%26a%3DCAog-J2zfQyCPTxSUYfzxp-f0vbR1A-QgQe8wZLVV_cxc4wSbRCk1NmPtzMYpOTU48AzIgEAUgTW0ieRWgRXLJDoaibAGLNMMIBBZKfB8dGrwLB3kbCqa8xcddaQGwa7k28yRaOb76nxVHImf28xnW9kfZWHTCMC8J4t3YDuDWHva0ZryHlXfFMhvYWVsnNxglk%26e%3D1769735533%26fl%3D%26r%3D631B66AA-70E2-4926-8C03-E7E9AD980FAF-1%26k%3D%24%7Buk%7D%26ckc%3Dcom.apple.clouddocs%26ckz%3DiCloud.is.workflow.my.workflows%26p%3D171%26s%3DK3YNvbYDreOhcQXSKuKp54-Gnjo&uk=GDvO49hVW7Dx_8DboqTJgw&f=File-short-b1-103725.xz&sz=2816 Code: // --- LOGGER SETUP --- const startTime = Date.now(); function log(msg) { const diff = Date.now() - startTime; console.log(`[${diff}ms] ${msg}`); } log("Script started."); // --- INPUT HANDLING --- let inputImage = null; let inputString = "default"; // Default seed if (args.images.length > 0) { log("Input detected: Image provided."); inputImage = args.images[0]; } else if (args.shortcutParameter) { if (typeof args.shortcutParameter === "string") { log(`Input detected: Text seed "${args.shortcutParameter}"`); inputString = args.shortcutParameter; } else { // Handle case where image is passed as parameter log("Input detected: Image object in parameter."); inputImage = args.shortcutParameter; } } else { log("No input found. Using default seed."); } // --- CONFIGURATION --- const BLOCK_SIZE = 4; // 4 = Retro/Fast, 2 = HD/Slow const NOISE_SCALE = 0.02; // Lower = Zoomed in (bigger clouds), Higher = Zoomed out const OCTAVES = 1; // Complexity of noise (Keep to 1 for speed in JS) // If overlaying on an image, use white fog with transparency. // If standalone, use opaque colorful plasma. const IS_OVERLAY = inputImage !== null; const NOISE_ALPHA = IS_OVERLAY ? 0.5 : 1.0; // --- PERLIN NOISE IMPLEMENTATION --- // We need a permutation table (0-255) to drive the noise. // We will shuffle this table using the user's seed. log("Initializing Random Seed..."); // 1. Simple Seeded RNG (Linear Congruential Generator) let seed = 0; for (let i = 0; i < inputString.length; i++) { seed = (Math.imul(31, seed) + inputString.charCodeAt(i)) | 0; } function random() { seed = (Math.imul(1664525, seed) + 1013904223) | 0; return ((seed >>> 0) / 4294967296); } // 2. Initialize Permutation Table const PERM_SIZE = 256; const p = new Uint8Array(PERM_SIZE * 2); // Fill with 0..255 let permutation = []; for (let i = 0; i < PERM_SIZE; i++) { permutation[i] = i; } // Shuffle using our seed for (let i = PERM_SIZE - 1; i > 0; i--) { let r = Math.floor(random() * (i + 1)); [permutation[i], permutation[r]] = [permutation[r], permutation[i]]; } // Double the array to avoid overflow wrapping for (let i = 0; i < PERM_SIZE * 2; i++) { p[i] = permutation[i % PERM_SIZE]; } log("Permutation table generated."); // 3. Perlin Math Helpers function fade(t) { return t * t * t * (t * (t * 6 - 15) + 10); } function lerp(t, a, b) { return a + t * (b - a); } function grad(hash, x, y, z) { const h = hash & 15; const u = h < 8 ? x : y; const v = h < 4 ? y : h === 12 || h === 14 ? x : z; return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v); } // 4. The Noise Function (2D) function perlin(x, y) { // Find unit cube that contains point let X = Math.floor(x) & 255; let Y = Math.floor(y) & 255; // Find relative x,y of point in cube x -= Math.floor(x); y -= Math.floor(y); // Compute fade curves let u = fade(x); let v = fade(y); // Hash coordinates of the 4 cube corners let A = p[X] + Y; let B = p[X + 1] + Y; // Add blended results from 4 corners return lerp(v, lerp(u, grad(p[A], x, y, 0), grad(p[B], x - 1, y, 0)), lerp(u, grad(p[A + 1], x, y - 1, 0), grad(p[B + 1], x - 1, y - 1, 0)) ); } // --- RENDERING --- let width, height; if (inputImage) { width = inputImage.size.width; height = inputImage.size.height; } else { width = 800; height = 800; } log(`Canvas dimensions set: ${width}x${height}`); let ctx = new DrawContext(); ctx.size = new Size(width, height); ctx.respectScreenScale = true; ctx.shouldAntialias = false; // Draw Background if (inputImage) { log("Drawing background image..."); ctx.drawImageInRect(inputImage, new Rect(0, 0, width, height)); } else { // Dark background for colorful noise ctx.setFillColor(new Color("#000000")); ctx.fillRect(new Rect(0, 0, width, height)); } // Helper: Map -1..1 to 0..255 function mapRange(val, inMin, inMax, outMin, outMax) { return (val - inMin) * (outMax - outMin) / (inMax - inMin) + outMin; } // Helper: Float to Hex function toHex(val) { let intVal = Math.floor(Math.max(0, Math.min(255, val))); let hex = intVal.toString(16); return hex.length === 1 ? "0" + hex : hex; } log(`Starting render loop (Block Size: ${BLOCK_SIZE})...`); let totalBlocks = (width * height) / (BLOCK_SIZE * BLOCK_SIZE); let count = 0; for (let px = 0; px < width; px += BLOCK_SIZE) { for (let py = 0; py < height; py += BLOCK_SIZE) { // Calculate Noise Value (-1.0 to 1.0) // We add seed offset to x/y to ensure different text makes different clouds let noiseVal = perlin(px * NOISE_SCALE, py * NOISE_SCALE); let color; if (IS_OVERLAY) { // White Fog Effect // Map noise -1..1 to Alpha 0..1 let alphaVal = mapRange(noiseVal, -1, 1, 0, NOISE_ALPHA); // White color with variable alpha color = new Color("FFFFFF", alphaVal); } else { // Colorful Plasma Effect // Map noise to 0..255 let v = mapRange(noiseVal, -1, 1, 0, 255); // Generate pseudo-palette based on noise value // This creates bands of color let r = v; let g = (v + 85) % 255; // Offset green let b = (v + 170) % 255; // Offset blue let hex = toHex(r) + toHex(g) + toHex(b); color = new Color(hex, 1.0); } ctx.setFillColor(color); ctx.fillRect(new Rect(px, py, BLOCK_SIZE, BLOCK_SIZE)); count++; } } log(`Render complete. Processed ${count} blocks.`); // --- OUTPUT --- let finalImage = ctx.getImage(); let fm = FileManager.local(); let tempPath = fm.joinPath(fm.temporaryDirectory(), "perlin_output.png"); fm.writeImage(tempPath, finalImage); log(`Image saved to: ${tempPath}`); Script.setShortcutOutput(tempPath); if (config.runsInApp) { QuickLook.present(finalImage); } log("Script finished."); Script.complete();

インフォメーション

バージョン: 1.0
リリース:
最終更新日:
アプリ:
許可:
写真
ファイル
カメラ

もっと見る Blazer