{"id":3901,"date":"2025-12-22T15:25:16","date_gmt":"2025-12-22T15:25:16","guid":{"rendered":"https:\/\/bkupdate.in\/?page_id=3901"},"modified":"2025-12-23T03:27:13","modified_gmt":"2025-12-23T03:27:13","slug":"name-and-dob-photo-joiner","status":"publish","type":"page","link":"https:\/\/bkupdate.in\/?page_id=3901","title":{"rendered":"Name and DOB Photo Joiner"},"content":{"rendered":"\n<!-- Name & DOB Photo Tool - WordPress Safe Version -->\n<div id=\"name-dob-tool\" class=\"w-full\">\n\n    <!-- External Libraries -->\n    <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n    <link href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/cropperjs\/1.5.12\/cropper.min.css\" rel=\"stylesheet\">\n    <link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/5.15.3\/css\/all.min.css\">\n    <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Space+Grotesk:wght@400;500;700&#038;display=swap\" rel=\"stylesheet\">\n\n    <style>\n        \/* Scoped Styles *\/\n        #name-dob-tool {\n            font-family: 'Inter', sans-serif;\n            --cyber-blue: #00F0FF;\n            --cyber-purple: #BD00FF;\n            --cyber-green: #10B981;\n            --cyber-bg: #0B0E14;\n        }\n\n        #name-dob-tool .cropper-view-box, \n        #name-dob-tool .cropper-face { \n            border-radius: 0; \/* Free crop usually rectangular *\/\n        }\n\n        #name-dob-tool img {\n            max-width: 100%;\n            display: block;\n        }\n\n        \/* Loader Overlay (Fixed) *\/\n        .nd-loader-overlay {\n            position: fixed; top: 0; left: 0; width: 100%; height: 100%;\n            background-color: var(--cyber-bg);\n            display: flex; flex-direction: column;\n            justify-content: center; align-items: center;\n            z-index: 99999; opacity: 1; transition: opacity 0.3s ease;\n            font-family: 'Space Grotesk', monospace;\n        }\n        .nd-loader-overlay.hidden { opacity: 0; pointer-events: none; }\n\n        .nd-spinner {\n            width: 80px; height: 80px; position: relative;\n        }\n        .nd-ring-outer {\n            position: absolute; inset: 0; border-top: 4px solid var(--cyber-blue);\n            border-radius: 50%; animation: ndSpin 1s linear infinite;\n        }\n        .nd-ring-inner {\n            position: absolute; inset: 0.5rem; border-bottom: 4px solid var(--cyber-purple);\n            border-radius: 50%; animation: ndSpin 1s linear infinite reverse;\n        }\n        .nd-text {\n            color: var(--cyber-blue); font-size: 0.875rem; margin-top: 20px;\n            font-weight: bold; letter-spacing: 2px;\n        }\n        .nd-loader-bar {\n            width: 250px; height: 4px; background: #333; margin-top: 15px; border-radius: 4px; overflow: hidden;\n        }\n        .nd-bar-fill {\n            height: 100%; background: var(--cyber-green); width: 0%; transition: width 0.3s;\n        }\n\n        @keyframes ndSpin { to { transform: rotate(360deg); } }\n    <\/style>\n\n    <div class=\"max-w-6xl mx-auto bg-gray-50 p-6 rounded-xl border border-gray-200\">\n        \n        <div class=\"text-center mb-8\">\n            <h1 class=\"text-3xl font-bold text-gray-800 mb-2\">Name and DOB Photo Joiner<\/h1>\n            <p class=\"text-gray-600\">High Quality mein photo banayein, crop karein aur uspar naam\/DOB jodein.<\/p>\n        <\/div>\n\n        <div class=\"grid grid-cols-1 lg:grid-cols-2 gap-8\">\n            <!-- Left Column -->\n            <div class=\"bg-white rounded-xl shadow-lg p-6 space-y-6\">\n                <!-- Upload -->\n                <div>\n                    <h2 class=\"text-xl font-bold text-gray-800 mb-4 border-b pb-2\">1. Photo Upload &#038; Crop<\/h2>\n                    <label for=\"nd_photoInput\" class=\"w-full flex items-center justify-center px-4 py-6 border-2 border-dashed border-gray-300 rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100 transition-colors\">\n                        <i class=\"fas fa-upload text-blue-500 text-2xl mr-3\"><\/i>\n                        <span id=\"nd_uploadLabel\" class=\"text-gray-600\">Click to choose photo&#8230;<\/span>\n                    <\/label>\n                    <input type=\"file\" id=\"nd_photoInput\" class=\"hidden\" accept=\"image\/*\">\n                    <div class=\"mt-4 w-full h-64 bg-gray-100 rounded-lg overflow-hidden border\">\n                        <img decoding=\"async\" id=\"nd_photoPreview\" src=\"\" alt=\"\">\n                    <\/div>\n                <\/div>\n                \n                <!-- Details -->\n                <div>\n                    <h2 class=\"text-xl font-bold text-gray-800 mb-4 border-b pb-2\">2. Enter Details<\/h2>\n                    <div class=\"space-y-4\">\n                        <div>\n                            <label class=\"block font-medium text-gray-700 mb-1\">Naam (Name):<\/label>\n                            <input type=\"text\" id=\"nd_nameInput\" placeholder=\"Enter Full Name\" class=\"w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none\">\n                        <\/div>\n                        <div>\n                            <label class=\"block font-medium text-gray-700 mb-1\">Janm Tithi (DOB):<\/label>\n                            <input type=\"date\" id=\"nd_dobInput\" class=\"w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none\">\n                        <\/div>\n                        <div>\n                            <label class=\"block font-medium text-gray-700 mb-1\">Target Size (KB):<\/label>\n                            <input type=\"number\" id=\"nd_targetSize\" value=\"50\" min=\"10\" class=\"w-full p-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none\">\n                        <\/div>\n                    <\/div>\n                <\/div>\n            <\/div>\n\n            <!-- Right Column -->\n            <div class=\"bg-white rounded-xl shadow-lg p-6\">\n                <h2 class=\"text-xl font-bold text-gray-800 mb-4 border-b pb-2\">3. Generate &#038; Download<\/h2>\n                <button id=\"nd_generateBtn\" class=\"w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-4 px-4 rounded-lg text-lg transition-colors shadow-md disabled:bg-gray-400 cursor-pointer\">\n                    Generate Image\n                <\/button>\n\n                <div id=\"nd_resultSection\" class=\"hidden mt-8\">\n                    <div class=\"flex flex-col items-center bg-green-50 p-4 rounded-lg border border-green-200 mb-4\">\n                        <p class=\"text-lg mb-2\">Final Size: <strong id=\"nd_finalSize\" class=\"text-green-700\"><\/strong><\/p>\n                        <a href=\"#\" id=\"nd_downloadLink\" download=\"photo-with-details.jpg\" class=\"w-full bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-4 rounded-lg text-center shadow\">\n                            <i class=\"fas fa-download mr-2\"><\/i> Download Image\n                        <\/a>\n                    <\/div>\n                    <img decoding=\"async\" id=\"nd_resultImage\" src=\"\" class=\"w-full max-w-sm mx-auto border-2 border-gray-200 rounded-lg shadow-sm\">\n                <\/div>\n            <\/div>\n        <\/div>\n        \n        <div class=\"mt-8 text-center text-gray-500 text-sm\">\n            <i class=\"fas fa-shield-alt text-green-500 mr-2\"><\/i> 100% Secure &#038; Private Processing\n        <\/div>\n    <\/div>\n\n    <canvas id=\"nd_resultCanvas\" class=\"hidden\"><\/canvas>\n\n    <!-- LOADER -->\n    <div id=\"nd_loader\" class=\"nd-loader-overlay hidden\">\n        <div class=\"nd-spinner\">\n            <div class=\"nd-ring-outer\"><\/div>\n            <div class=\"nd-ring-inner\"><\/div>\n        <\/div>\n        <div class=\"nd-text\" id=\"nd_loaderText\">PROCESSING<\/div>\n        <div class=\"nd-loader-bar\">\n            <div class=\"nd-bar-fill\" id=\"nd_loaderBar\"><\/div>\n        <\/div>\n    <\/div>\n\n<\/div>\n\n<!-- Scripts -->\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/cropperjs\/1.5.12\/cropper.min.js\"><\/script>\n<script>\n(function() {\n    document.addEventListener('DOMContentLoaded', function() {\n        \/\/ Scoped Selectors\n        const getEl = (id) => document.querySelector(`#name-dob-tool #${id}`);\n\n        const photoInput = getEl('nd_photoInput');\n        const uploadLabel = getEl('nd_uploadLabel');\n        const nameInput = getEl('nd_nameInput');\n        const dobInput = getEl('nd_dobInput');\n        const photoPreview = getEl('nd_photoPreview');\n        const targetSizeInput = getEl('nd_targetSize');\n        const generateBtn = getEl('nd_generateBtn');\n        const resultSection = getEl('nd_resultSection');\n        const resultCanvas = getEl('nd_resultCanvas');\n        const resultImage = getEl('nd_resultImage');\n        const finalSizeDisplay = getEl('nd_finalSize');\n        const downloadLink = getEl('nd_downloadLink');\n        \n        const loader = getEl('nd_loader');\n        const loaderText = getEl('nd_loaderText');\n        const loaderBar = getEl('nd_loaderBar');\n\n        let photoCropper = null;\n        const FINAL_WIDTH = 800;\n        const TEXT_RATIO = 0.20;\n\n        photoInput.addEventListener('change', (e) => {\n            const file = e.target.files[0];\n            if (!file) return;\n\n            uploadLabel.innerText = file.name;\n            const reader = new FileReader();\n            reader.onload = (event) => {\n                photoPreview.src = event.target.result;\n                if (photoCropper) photoCropper.destroy();\n                \n                \/\/ FREE CROP (No Aspect Ratio)\n                photoCropper = new Cropper(photoPreview, {\n                    aspectRatio: NaN,  \/\/ User can crop freely\n                    viewMode: 1,\n                    background: false,\n                    autoCropArea: 1\n                });\n            };\n            reader.readAsDataURL(file);\n        });\n\n        generateBtn.addEventListener('click', () => {\n            if (!photoCropper) {\n                alert('Please upload a photo first!');\n                return;\n            }\n\n            loader.classList.remove('hidden');\n            generateBtn.disabled = true;\n\n            const logs = [\"Analyzing...\", \"Cropping...\", \"Adding Text...\", \"Compressing...\", \"Finalizing...\"];\n            let i = 0;\n            loaderBar.style.width = \"0%\";\n            loaderText.innerText = \"STARTING...\";\n\n            const interval = setInterval(() => {\n                if(i < logs.length) {\n                    loaderText.innerText = \"> \" + logs[i];\n                    loaderBar.style.width = ((i + 1) * 20) + \"%\";\n                    i++;\n                } else {\n                    clearInterval(interval);\n                }\n            }, 900);\n\n            setTimeout(async () => {\n                clearInterval(interval);\n                loaderBar.style.width = \"100%\";\n\n                const croppedCanvas = photoCropper.getCroppedCanvas({ imageSmoothingQuality: 'high' });\n                const ar = croppedCanvas.width \/ croppedCanvas.height;\n                const photoH = FINAL_WIDTH \/ ar;\n                const textH = photoH * TEXT_RATIO;\n\n                const ctx = resultCanvas.getContext('2d');\n                resultCanvas.width = FINAL_WIDTH;\n                resultCanvas.height = photoH + textH;\n\n                ctx.fillStyle = 'white';\n                ctx.fillRect(0, 0, resultCanvas.width, resultCanvas.height);\n                ctx.drawImage(croppedCanvas, 0, 0, FINAL_WIDTH, photoH);\n\n                const name = nameInput.value.trim();\n                const dob = dobInput.value;\n                let dobStr = '';\n                if(dob) {\n                    const [y, m, d] = dob.split('-');\n                    dobStr = `DOB: ${d}-${m}-${y}`;\n                }\n\n                ctx.font = `bold ${textH * 0.35}px Arial`;\n                ctx.fillStyle = 'black';\n                ctx.textAlign = 'center';\n\n                if(name) ctx.fillText(name, FINAL_WIDTH\/2, photoH + (textH * 0.4));\n                if(dobStr) ctx.fillText(dobStr, FINAL_WIDTH\/2, photoH + (textH * 0.85));\n\n                \/\/ Compression Logic\n                const targetB = parseInt(targetSizeInput.value) * 1024;\n                let q = 0.95;\n                let blob = await new Promise(r => resultCanvas.toBlob(r, 'image\/jpeg', q));\n\n                while(blob.size > targetB && q > 0.1) {\n                    q -= 0.05;\n                    blob = await new Promise(r => resultCanvas.toBlob(r, 'image\/jpeg', q));\n                }\n\n                const url = URL.createObjectURL(blob);\n                resultImage.src = url;\n                downloadLink.href = url;\n                finalSizeDisplay.innerText = (blob.size\/1024).toFixed(1) + \" KB\";\n\n                loader.classList.add('hidden');\n                resultSection.classList.remove('hidden');\n                generateBtn.disabled = false;\n                resultSection.scrollIntoView({ behavior: 'smooth' });\n\n            }, 5000);\n        });\n    });\n})();\n<\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Name and DOB Photo Joiner High Quality mein photo banayein, crop karein aur uspar naam\/DOB jodein. 1. Photo &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Name and DOB Photo Joiner\" class=\"read-more button\" href=\"https:\/\/bkupdate.in\/?page_id=3901#more-3901\" aria-label=\"Read more about Name and DOB Photo Joiner\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-3901","page","type-page","status-publish"],"_links":{"self":[{"href":"https:\/\/bkupdate.in\/index.php?rest_route=\/wp\/v2\/pages\/3901","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bkupdate.in\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bkupdate.in\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bkupdate.in\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bkupdate.in\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3901"}],"version-history":[{"count":3,"href":"https:\/\/bkupdate.in\/index.php?rest_route=\/wp\/v2\/pages\/3901\/revisions"}],"predecessor-version":[{"id":3921,"href":"https:\/\/bkupdate.in\/index.php?rest_route=\/wp\/v2\/pages\/3901\/revisions\/3921"}],"wp:attachment":[{"href":"https:\/\/bkupdate.in\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}