diff --git a/__tests__/base64ToImage.test.js b/__tests__/base64ToImage.test.js
new file mode 100644
index 0000000..73149b7
--- /dev/null
+++ b/__tests__/base64ToImage.test.js
@@ -0,0 +1,77 @@
+const fs = require("fs");
+const path = require("path");
+const { JSDOM } = require("jsdom");
+
+function waitForEvent(target, eventName, timeoutMs = 3000) {
+ return new Promise((resolve, reject) => {
+ const t = setTimeout(() => reject(new Error(`Timed out waiting for ${eventName}`)), timeoutMs);
+ target.addEventListener(eventName, () => {
+ clearTimeout(t);
+ resolve();
+ }, { once: true });
+ });
+}
+
+test("Base64 to Image: Preview converts valid base64 and shows output", async () => {
+ const htmlPath = path.join(__dirname, "..", "base64-to-image.html");
+ const html = fs.readFileSync(htmlPath, "utf8");
+
+ const dom = new JSDOM(html, {
+ runScripts: "dangerously",
+ resources: "usable",
+ pretendToBeVisual: true,
+ beforeParse(window) {
+ // Mock fetch for footer/sidebar includes
+ window.fetch = () =>
+ Promise.resolve({
+ text: () => Promise.resolve(""),
+ });
+
+ // Mock object URL APIs used for download link
+ window.URL.createObjectURL = () => "blob:mock-url";
+ window.URL.revokeObjectURL = () => {};
+
+ // Mock clipboard (not used in this test but prevents errors if clicked elsewhere)
+ window.navigator.clipboard = {
+ writeText: () => Promise.resolve(),
+ };
+ },
+ });
+
+ // Wait until all scripts run (your code attaches listeners on DOMContentLoaded + load)
+ await waitForEvent(dom.window, "load");
+
+ const base64Input = dom.window.document.getElementById("base64-input");
+ const convertBtn = dom.window.document.getElementById("convert-btn");
+
+ // Ensure demo base64 was populated on load (your code does this)
+ expect(base64Input.value).toMatch(/^iVBORw0KGgo/);
+
+ // Click Preview
+ convertBtn.click();
+
+ // Give async handler time to run
+ await new Promise((r) => setTimeout(r, 50));
+
+ const outputSection = dom.window.document.getElementById("output-section");
+ const previewImg = dom.window.document.getElementById("preview-img");
+ const downloadBtn = dom.window.document.getElementById("download-btn");
+ const detectedType = dom.window.document.getElementById("detected-type");
+ const estimatedSize = dom.window.document.getElementById("estimated-size");
+ const base64Length = dom.window.document.getElementById("base64-length");
+
+ // Output should be visible
+ expect(outputSection.classList.contains("hidden")).toBe(false);
+
+ // Preview image should be set to a data URL
+ expect(previewImg.getAttribute("src")).toMatch(/^data:image\/png;base64,/);
+
+ // Download should be wired up
+ expect(downloadBtn.getAttribute("href")).toBe("blob:mock-url");
+ expect(downloadBtn.getAttribute("download")).toBe("image.png");
+
+ // Meta fields should be filled
+ expect(detectedType.textContent).toBe("image/png");
+ expect(estimatedSize.textContent).not.toBe("—");
+ expect(base64Length.textContent).toContain("chars");
+});
diff --git a/all_tools/script.js b/all_tools/script.js
index bc8fa76..e1415f0 100644
--- a/all_tools/script.js
+++ b/all_tools/script.js
@@ -9,6 +9,7 @@ const toolsData = [
{ name: "URL Decoder", description: "Decode URL-encoded strings", category: "encoders", url: "../url-decoder.html", icon: "🔓" },
{ name: "Base64 Encoder", description: "Encode to Base64 format", category: "encoders", url: "../base64-encoder.html", icon: "📤" },
{ name: "Base64 Decoder", description: "Decode Base64 strings", category: "encoders", url: "../base64-decoder.html", icon: "📥" },
+ { name: "Base64 to Image", description: "Preview & download images from Base64", category: "encoders", url: "../base64-to-image.html", icon: "🖼️" },
{ name: "Base32 Encoder", description: "Encode to Base32 format", category: "encoders", url: "../base32encode/index.html", icon: "📤" },
{ name: "Base32 Decoder", description: "Decode Base32 strings", category: "encoders", url: "../base32decode/index.html", icon: "📥" },
{ name: "Hash Generator", description: "Generate secure hashes", category: "encoders", url: "../hash-generator.html", icon: "🔐" },
diff --git a/base64-to-image.html b/base64-to-image.html
new file mode 100644
index 0000000..5629a7a
--- /dev/null
+++ b/base64-to-image.html
@@ -0,0 +1,385 @@
+
+
+
+
+
+
+
+ Base64 to Image - Developer Toolkit | DevDunia
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Base64 to Image
+
+
+ Paste Base64 image data to preview it and download as an image file.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
If you paste a data URL, type is auto-detected.
+
+
+
+
+
No spaces needed. Example: my_logo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Preview
+
+
+
+
![Base64 Preview]()
+
+
+
+
+
+
Download
+
After preview, you can download the image to your device.
+
+
+
+
+
+ Detected Type:
+ —
+
+
+ Estimated Size:
+ —
+
+
+ Base64 Length:
+ —
+
+
+
+
+
+
+
+
Tips
+
+ - If your Base64 already starts with data:image/...;base64, you can paste it directly.
+ - If you paste raw Base64, choose the correct image type from the dropdown.
+ - For very large images, preview might take a few seconds.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/final_sidebar.html b/final_sidebar.html
index 8ffbff8..6c5d8e0 100644
--- a/final_sidebar.html
+++ b/final_sidebar.html
@@ -67,6 +67,10 @@ Encoder
📥
Base64 Decoder
+