1(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2132],{93162:function(t,a,n){var r,o;void 0!==(o="function"==typeof(r=function(){"use strict";function c(t,a,n){var r=new XMLHttpRequest;r.open("GET",t),r.responseType="blob",r.onload=function(){o(r.response,a,n)},r.onerror=function(){console.error("could not download file")},r.send()}function d(t){var a=new XMLHttpRequest;a.open("HEAD",t,!1);try{a.send()}catch(t){}return 200<=a.status&&299>=a.status}function e(t){try{t.dispatchEvent(new MouseEvent("click"))}catch(n){var a=document.createEvent("MouseEvents");a.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),t.dispatchEvent(a)}}var a="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof n.g&&n.g.global===n.g?n.g:void 0,r=a.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),o=a.saveAs||("object"!=typeof window||window!==a?function(){}:"download"in HTMLAnchorElement.prototype&&!r?function(t,n,r){var o=a.URL||a.webkitURL,s=document.createElement("a");n=n||t.name||"download",s.download=n,s.rel="noopener","string"==typeof t?(s.href=t,s.origin===location.origin?e(s):d(s.href)?c(t,n,r):e(s,s.target="_blank")):(s.href=o.createObjectURL(t),setTimeout(function(){o.revokeObjectURL(s.href)},4e4),setTimeout(function(){e(s)},0))}:"msSaveOrOpenBlob"in navigator?function(t,a,n){if(a=a||t.name||"download","string"!=typeof t){var r;navigator.msSaveOrOpenBlob((void 0===(r=n)?r={autoBom:!1}:"object"!=typeof r&&(console.warn("Deprecated: Expected third argument to be a object"),r={autoBom:!r}),r.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob(["\uFEFF",t],{type:t.type}):t),a)}else if(d(t))c(t,a,n);else{var o=document.createElement("a");o.href=t,o.target="_blank",setTimeout(function(){e(o)})}}:function(t,n,o,s){if((s=s||open("","_blank"))&&(s.document.title=s.document.body.innerText="downloading..."),"string"==typeof t)return c(t,n,o);var l="application/octet-stream"===t.type,i=/constructor/i.test(a.HTMLElement)||a.safari,m=/CriOS\/[\d]+/.test(navigator.userAgent);if((m||l&&i||r)&&"undefined"!=typeof FileReader){var u=new FileReader;u.onloadend=function(){var t=u.result;t=m?t:t.replace(/^data:[^;]*;/,"data:attachment/file;"),s?s.location.href=t:location=t,s=null},u.readAsDataURL(t)}else{var x=a.URL||a.webkitURL,p=x.createObjectURL(t);s?s.location=p:location.href=p,s=null,setTimeout(function(){x.revokeObjectURL(p)},4e4)}});a.saveAs=o.saveAs=o,t.exports=o})?r.apply(a,[]):r)&&(t.exports=o)},11455:function(t,a,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/tools/image-watermark",function(){return n(36124)}])},36124:function(t,a,n){"use strict";n.r(a),n.d(a,{default:function(){return ImageWatermarkPage}});var r=n(85893),o=n(67294),s=n(9008),l=n.n(s),i=n(93162),m=n(52091),u=n(79133),x=n(16348);let p=[["top-left","top-center","top-right"],["middle-left","center","middle-right"],["bottom-left","bottom-center","bottom-right"]];function ImageWatermarkPage(){let[t,a]=(0,o.useState)(null),[n,s]=(0,o.useState)(""),[g,h]=(0,o.useState)(null),[b,f]=(0,o.useState)("text"),[w,j]=(0,o.useState)("\xa9 McStumble"),[v,y]=(0,o.useState)(5),[N,k]=(0,o.useState)("#ffffff"),[C,S]=(0,o.useState)(50),[A,E]=(0,o.useState)(0),[I,T]=(0,o.useState)("bottom-right"),[L,R]=(0,o.useState)(!1),[M,O]=(0,o.useState)(20),[P,W]=(0,o.useState)("png"),_=(0,o.useRef)(null),loadImageFile=t=>new Promise((a,n)=>{let r=new Image;r.onload=()=>a(r),r.onerror=()=>n(Error("Could not load image.")),r.src=URL.createObjectURL(t)}),F=(0,o.useCallback)(async t=>{var n;let r=null===(n=t.target.files)||void 0===n?void 0:n[0];t.target.value=null,r&&r.type.startsWith("image/")&&(s(r.name),a(await loadImageFile(r)))},[]),U=(0,o.useCallback)(async t=>{var a;let n=null===(a=t.target.files)||void 0===a?void 0:a[0];t.target.value=null,n&&n.type.startsWith("image/")&&h(await loadImageFile(n))},[]);(0,o.useEffect)(()=>{let a=_.current;if(!a||!t)return;a.width=t.naturalWidth,a.height=t.naturalHeight;let n=a.getContext("2d");n.drawImage(t,0,0),n.save(),n.globalAlpha=C/100;let r=.03*a.width,drawOne=(t,r)=>{if(n.save(),n.translate(t,r),n.rotate(A*Math.PI/180),"text"===b){let t=v/100*a.width;n.font="bold ".concat(t,"px Arial, sans-serif"),n.fillStyle=N,n.textAlign="center",n.textBaseline="middle",n.fillText(w,0,0)}
1else if(g){let t=M/100*a.width,r=t*(g.naturalHeight/g.naturalWidth);n.drawImage(g,-t/2,-r/2,t,r)}n.restore()},o="text"===b?v/100*a.width*Math.max(1,w.length)*.55:M/100*a.width,s="text"===b?v/100*a.width*1.4:g?M/100*a.width*(g.naturalHeight/g.naturalWidth):0;if(L){let t=o+.1*a.width,n=s+.12*a.height;for(let r=n/2;r<a.height+n;r+=n)for(let n=t/2;n<a.width+t;n+=t)drawOne(n,r)}else{let[t,n]="center"===I?["middle","center"]:I.split("-"),l="left"===n?r+o/2:"right"===n?a.width-r-o/2:a.width/2,i="top"===t?r+s/2:"bottom"===t?a.height-r-s/2:a.height/2;drawOne(l,i)}n.restore()},[t,g,b,w,v,N,C,A,I,L,M]);let B=(0,o.useCallback)(()=>{let t=_.current;if(!t)return;let a="jpeg"===P?"image/jpeg":"image/png";t.toBlob(t=>{let a=n.replace(/\.[^.]+$/,"")||"image";(0,i.saveAs)(t,"".concat(a,"-watermarked.").concat("jpeg"===P?"jpg":"png"))},a,.92)},[P,n]);return(0,r.jsxs)("div",{className:"min-h-screen bg-background text-text-main",children:[(0,r.jsx)(u.Z,{}),(0,r.jsxs)("div",{className:"pt-12 px-4 py-8 max-w-5xl mx-auto",children:[(0,r.jsxs)(l(),{children:[(0,r.jsx)("title",{children:"Add Watermark to Image (Free, In-Browser) | McStumble Tools"}),(0,r.jsx)("meta",{name:"description",content:"Add a text or logo watermark to photos â position, tile, rotate, and adjust opacity. Free and private: images never leave your browser."}),(0,r.jsx)("link",{rel:"canonical",href:"https://mcstumble.com/tools/image-watermark"}),(0,r.jsx)("meta",{property:"og:title",content:"Image Watermark Adder | McStumble Tools"}),(0,r.jsx)("meta",{property:"og:description",content:"Add text or logo watermarks to images, entirely in your browser."}),(0,r.jsx)("meta",{property:"og:type",content:"website"}),(0,r.jsx)("meta",{property:"og:url",content:"https://mcstumble.com/tools/image-watermark"}),(0,r.jsx)("meta",{property:"og:site_name",content:"McStumble Tools"}),(0,r.jsx)("meta",{name:"twitter:card",content:"summary"}),(0,r.jsx)("meta",{name:"twitter:title",content:"Image Watermark Adder | McStumble Tools"}),(0,r.jsx)("meta",{name:"twitter:description",content:"Add text or logo watermarks to images, entirely in your browser."})]}),(0,r.jsxs)(x.Z,{toolId:"image-watermark",name:"Image Watermark Adder",description:"Add a text or logo watermark to photos â position, tile, rotate, and adjust opacity.",applicationCategory:"MultimediaApplication",children:[(0,r.jsxs)("div",{className:"flex items-center mb-6",children:[(0,r.jsx)("div",{className:"w-10 h-10 rounded-lg bg-purple-500/20 flex items-center justify-center mr-3",children:(0,r.jsx)(m.eNt,{className:"text-purple-600 text-xl"})}),(0,r.jsx)("h1",{className:"text-2xl md:text-3xl font-bold",children:"Image Watermark Adder"})]}),(0,r.jsx)("p",{className:"text-text-muted mb-6 max-w-2xl",children:"Protect or brand your photos with a text or logo watermark. Position it in any corner, tile it across the whole image, and tune size, rotation, and opacity â all locally in your browser."}),(0,r.jsxs)("div",{className:"retro-window mb-6",children:[(0,r.jsx)("div",{className:"retro-window-titlebar",children:(0,r.jsx)("span",{className:"retro-window-title",children:"1. Choose an image"})}),(0,r.jsx)("div",{className:"retro-window-content",children:(0,r.jsxs)("label",{className:"brand-card flex cursor-pointer flex-col items-center justify-center gap-2 border-dashed p-8 text-center",children:[(0,r.jsx)(m.H3h,{className:"text-3xl text-brand-cyan"}),(0,r.jsx)("span",{className:"font-bold",children:n||"Click to select an image"}),(0,r.jsx)("span",{className:"text-sm text-text-muted",children:"PNG, JPG, WebP â stays on your device"}),(0,r.jsx)("input",{type:"file",accept:"image/*",onChange:F,className:"hidden"})]})})]}),t&&(0,r.jsxs)("div",{className:"grid gap-6 md:grid-cols-[320px,1fr]",children:[(0,r.jsxs)("div",{className:"retro-window self-start",children:[(0,r.jsx)("div",{className:"retro-window-titlebar",children:(0,r.jsx)("span",{className:"retro-window-title",children:"2. Watermark settings"})}),(0,r.jsxs)("div",{className:"retro-window-content space-y-4",children:[(0,r.jsxs)("div",{className:"flex gap-2",children:[(0,r.jsxs)("button",{type:"button",onClick:()=>f("text"),className:"flex-1 rounded-lg border-2 px-3 py-2 text-sm font-extrabold ".concat("text"===b?"border-slate-950 bg-brand-cyan/20":"border-border-main"),children:[(0,r.jsx)(m.wT5,{className:"mr-1.5 inline"})," Text"]}),(0,r.jsxs)("button",{type:"button",onClick:()=>f("logo"),className:"flex-1 rounded-lg border-2 px-3 py-2 text-sm font-extrabold ".concat("logo"===b?"border-slate-950 bg-brand-cyan/20":"border-border-main"),children:[(0,r.jsx)(m.H3h,{className:"mr-1.5 inline"})," Logo"]})]}),"text"===b?(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("div",{children:[(0,r.jsx)("label",{className:"mb-1 block text-sm font-bold",children:"Watermark text"}),(0,r.jsx)("input",{type:"text",value:w,onChange:t=>j(t.target.value),className:"retro-input w-full"})]}),(0,r.jsxs)("div",{children:[(0,r.jsxs)("label",{className:"mb-1 block text-sm font-bold",children:["Size: ",v,"% of width"]}),(0,r.jsx)("input",{type:"range",min:"1",max:"20",step:"0.5",value:v,onCh
1ange:t=>y(parseFloat(t.target.value)),className:"w-full"})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("label",{className:"mb-1 block text-sm font-bold",children:"Color"}),(0,r.jsx)("input",{type:"color",value:N,onChange:t=>k(t.target.value),className:"h-9 w-full cursor-pointer"})]})]}):(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)("label",{className:"brand-card flex cursor-pointer flex-col items-center gap-1 border-dashed p-4 text-center text-sm",children:[(0,r.jsx)("span",{className:"font-bold",children:g?"Logo loaded â click to change":"Click to select a logo (PNG works best)"}),(0,r.jsx)("input",{type:"file",accept:"image/*",onChange:U,className:"hidden"})]}),(0,r.jsxs)("div",{children:[(0,r.jsxs)("label",{className:"mb-1 block text-sm font-bold",children:["Logo size: ",M,"% of width"]}),(0,r.jsx)("input",{type:"range",min:"5",max:"60",step:"1",value:M,onChange:t=>O(parseInt(t.target.value,10)),className:"w-full"})]})]}),(0,r.jsxs)("div",{children:[(0,r.jsxs)("label",{className:"mb-1 block text-sm font-bold",children:["Opacity: ",C,"%"]}),(0,r.jsx)("input",{type:"range",min:"5",max:"100",step:"5",value:C,onChange:t=>S(parseInt(t.target.value,10)),className:"w-full"})]}),(0,r.jsxs)("div",{children:[(0,r.jsxs)("label",{className:"mb-1 block text-sm font-bold",children:["Rotation: ",A,"\xb0"]}),(0,r.jsx)("input",{type:"range",min:"-90",max:"90",step:"5",value:A,onChange:t=>E(parseInt(t.target.value,10)),className:"w-full"})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("label",{className:"mb-1 block text-sm font-bold",children:"Placement"}),(0,r.jsxs)("label",{className:"mb-2 flex items-center gap-2 text-sm cursor-pointer",children:[(0,r.jsx)("input",{type:"checkbox",checked:L,onChange:t=>R(t.target.checked)})," Tile across the whole image"]}),!L&&(0,r.jsx)("div",{className:"grid grid-cols-3 gap-1",children:p.flat().map(t=>(0,r.jsx)("button",{type:"button",onClick:()=>T(t),title:t,className:"h-8 rounded border-2 ".concat(I===t?"border-slate-950 bg-brand-cyan/30":"border-border-main hover:border-brand-cyan")},t))})]}),(0,r.jsxs)("div",{children:[(0,r.jsx)("label",{className:"mb-1 block text-sm font-bold",children:"Download format"}),(0,r.jsxs)("select",{className:"retro-select w-full",value:P,onChange:t=>W(t.target.value),children:[(0,r.jsx)("option",{value:"png",children:"PNG (lossless)"}),(0,r.jsx)("option",{value:"jpeg",children:"JPG (smaller)"})]})]}),(0,r.jsxs)("button",{className:"retro-button-primary w-full",onClick:B,children:[(0,r.jsx)(m.aBF,{})," Download watermarked image"]})]})]}),(0,r.jsxs)("div",{className:"retro-window self-start",children:[(0,r.jsx)("div",{className:"retro-window-titlebar",children:(0,r.jsx)("span",{className:"retro-window-title",children:"3. Preview"})}),(0,r.jsx)("div",{className:"retro-window-content",children:(0,r.jsx)("canvas",{ref:_,className:"w-full rounded border border-border-main bg-background-accent"})})]})]})]})]})]})}},9008:function(t,a,n){t.exports=n(79201)}},function(t){t.O(0,[6490,9133,7899,6348,9774,2888,179],function(){return t(t.s=11455)}),_N_E=t.O()}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.