আপনার যদি একক পিক্সেলের রঙের পরিবর্তে কোনও আয়তক্ষেত্রাকার গড় গড় রঙ প্রয়োজন, দয়া করে এই অন্যান্য প্রশ্নটি একবার দেখুন:
👉 জাভাস্ক্রিপ্ট - কোনও চিত্রের নির্দিষ্ট অঞ্চল থেকে গড় রঙ পান
যাইহোক, উভয়ই খুব একইভাবে সম্পন্ন হয়:
An একটি চিত্র বা ক্যানভাস থেকে একটি একক পিক্সেলের রঙ / মান পাওয়া
একক পিক্সেলের রঙ পেতে, আপনি প্রথমে সেই চিত্রটি কোনও ক্যানভাসে আঁকবেন, যা আপনি ইতিমধ্যে করেছেন:
const image = document.getElementById('image');
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const width = image.width;
const height = image.height;
canvas.width = width;
canvas.height = height;
context.drawImage(image, 0, 0, width, height);
এবং তারপরে একটি একক পিক্সেলের মান পান:
const data = context.getImageData(X, Y, 1, 1).data;
Image সমস্ত ইমেজ ডেটা একবারে পেয়ে দ্রুত গতি বাড়ান
পুরো ইমেজের মান পেতে আপনাকে এই একই ক্যানভাস রেন্ডারিং কনটেক্সট 2 ডি.জেটআইমেজডেটা () ব্যবহার করতে হবে যা আপনি এর তৃতীয় এবং চতুর্থ প্যারাম পরিবর্তন করে করেন। এই ফাংশনের স্বাক্ষরটি হ'ল:
ImageData ctx.getImageData(sx, sy, sw, sh);
sx: আয়তক্ষেত্রের উপরের বাম কোণের x স্থানাঙ্ক যা থেকে চিত্রের ডেটা বের করা হবে।
sy: আয়তক্ষেত্রের উপরের বাম কোণের y স্থানাঙ্ক যা থেকে চিত্রের ডেটা বের করা হবে।
sw: আয়তক্ষেত্রটির প্রস্থ যা থেকে চিত্রের ডেটা বের করা হবে।
sh: আয়তক্ষেত্রের উচ্চতা যেখান থেকে ইমেজডাটা বের করা হবে।
আপনি দেখতে পান এটি কোনও ImageDataবস্তু, যা যা তা ফিরিয়ে দেয় । এখানে গুরুত্বপূর্ণ অংশটি হ'ল সেই অবজেক্টটির একটি .dataসম্পত্তি রয়েছে যা আমাদের সমস্ত পিক্সেল মান রাখে।
তবে নোট করুন যে .dataসম্পত্তিটি 1-মাত্রিক Uint8ClampedArray, যার অর্থ পিক্সেলের সমস্ত উপাদান সমতল হয়েছে, সুতরাং আপনি এমন কিছু পেয়ে যাচ্ছেন যা দেখায়:
ধরা যাক আপনার কাছে 2x2 চিত্র রয়েছে:
RED PIXEL | GREEN PIXEL
BLUE PIXEL | TRANSPARENT PIXEL
তারপরে, আপনি তাদের এইভাবে পাবেন:
[ 255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, 0, 0, 0, 0 ]
| RED PIXEL | GREEN PIXEL | BLUE PIXEL | TRANSPAERENT PIXEL |
| 1ST PIXEL | 2ND PIXEL | 3RD PIXEL | 4TH PIXEL |
যেহেতু কলিং getImageDataএকটি ধীর অপারেশন, আপনি সমস্ত চিত্রের ডেটা ( sw= চিত্র প্রস্থ, sh= চিত্রের উচ্চতা) পেতে কেবল একবার কল করতে পারেন ।
এর পরে, উপরের উদাহরণে, তোমাদের মধ্যে উপাদান অ্যাক্সেস করতে চান তাহলে TRANSPARENT PIXEL, যে অবস্থানে এক x = 1, y = 1এই কাল্পনিক ইমেজ, আপনি তার প্রথম সূচক খুঁজতে হবে iতার মধ্যে ImageData'র dataহিসাবে সম্পত্তি:
const i = (y * imageData.width + x) * 4;
✨ আসুন এটি দেখতে দিন
const solidColor = document.getElementById('solidColor');
const alphaColor = document.getElementById('alphaColor');
const solidWeighted = document.getElementById('solidWeighted');
const solidColorCode = document.getElementById('solidColorCode');
const alphaColorCode = document.getElementById('alphaColorCode');
const solidWeightedCOde = document.getElementById('solidWeightedCode');
const brush = document.getElementById('brush');
const image = document.getElementById('image');
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const width = image.width;
const height = image.height;
const BRUSH_SIZE = brush.offsetWidth;
const BRUSH_CENTER = BRUSH_SIZE / 2;
const MIN_X = image.offsetLeft + 4;
const MAX_X = MIN_X + width - 1;
const MIN_Y = image.offsetTop + 4;
const MAX_Y = MIN_Y + height - 1;
canvas.width = width;
canvas.height = height;
context.drawImage(image, 0, 0, width, height);
const imageDataData = context.getImageData(0, 0, width, height).data;
function sampleColor(clientX, clientY) {
if (clientX < MIN_X || clientX > MAX_X || clientY < MIN_Y || clientY > MAX_Y) {
requestAnimationFrame(() => {
brush.style.transform = `translate(${ clientX }px, ${ clientY }px)`;
solidColorCode.innerText = solidColor.style.background = 'rgb(0, 0, 0)';
alphaColorCode.innerText = alphaColor.style.background = 'rgba(0, 0, 0, 0.00)';
solidWeightedCode.innerText = solidWeighted.style.background = 'rgb(0, 0, 0)';
});
return;
}
const imageX = clientX - MIN_X;
const imageY = clientY - MIN_Y;
const i = (imageY * width + imageX) * 4;
const R = imageDataData[i];
const G = imageDataData[i + 1];
const B = imageDataData[i + 2];
const A = imageDataData[i + 3] / 255;
const iA = 1 - A;
const wR = (R * A + 255 * iA) | 0;
const wG = (G * A + 255 * iA) | 0;
const wB = (B * A + 255 * iA) | 0;
requestAnimationFrame(() => {
brush.style.transform = `translate(${ clientX }px, ${ clientY }px)`;
solidColorCode.innerText = solidColor.style.background
= `rgb(${ R }, ${ G }, ${ B })`;
alphaColorCode.innerText = alphaColor.style.background
= `rgba(${ R }, ${ G }, ${ B }, ${ A.toFixed(2) })`;
solidWeightedCode.innerText = solidWeighted.style.background
= `rgb(${ wR }, ${ wG }, ${ wB })`;
});
}
document.onmousemove = (e) => sampleColor(e.clientX, e.clientY);
sampleColor(MIN_X, MIN_Y);
body {
margin: 0;
height: 100vh;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
cursor: none;
font-family: monospace;
overflow: hidden;
}
#image {
border: 4px solid white;
border-radius: 2px;
box-shadow: 0 0 32px 0 rgba(0, 0, 0, .25);
width: 150px;
box-sizing: border-box;
}
#brush {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
width: 1px;
height: 1px;
mix-blend-mode: exclusion;
border-radius: 100%;
}
#brush::before,
#brush::after {
content: '';
position: absolute;
background: magenta;
}
#brush::before {
top: -16px;
left: 0;
height: 33px;
width: 100%;
}
#brush::after {
left: -16px;
top: 0;
width: 33px;
height: 100%;
}
#samples {
position: relative;
list-style: none;
padding: 0;
width: 250px;
}
#samples::before {
content: '';
position: absolute;
top: 0;
left: 27px;
width: 2px;
height: 100%;
background: black;
border-radius: 1px;
}
#samples > li {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 56px;
}
#samples > li + li {
margin-top: 8px;
}
.sample {
position: absolute;
top: 50%;
left: 16px;
transform: translate(0, -50%);
display: block;
width: 24px;
height: 24px;
border-radius: 100%;
box-shadow: 0 0 16px 4px rgba(0, 0, 0, .25);
margin-right: 8px;
}
.sampleLabel {
font-weight: bold;
margin-bottom: 8px;
}
.sampleCode {
}
<img id="image" src="data:image/gif;base64,R0lGODlhSwBLAPEAACMfIO0cJAAAAAAAACH/C0ltYWdlTWFnaWNrDWdhbW1hPTAuNDU0NTUAIf4jUmVzaXplZCBvbiBodHRwczovL2V6Z2lmLmNvbS9yZXNpemUAIfkEBQAAAgAsAAAAAEsASwAAAv+Uj6mb4A+QY7TaKxvch+MPKpC0eeUUptdomOzJqnLUvnFcl7J6Pzn9I+l2IdfII8DZiCnYsYdK4qRTptAZwQKRVK71CusOgx2nFRrlhMu+33o2NEalC6S9zQvfi3Mlnm9WxeQ396F2+HcQsMjYGEBRVbhy5yOp6OgIeVIHpEnZyYCZ6cklKBJX+Kgg2riqKoayOWl2+VrLmtDqBptIOjZ6K4qAeSrL8PcmHExsgMs2dpyIxPpKvdhM/YxaTMW2PGr9GP76BN3VHTMurh7eoU14jsc+P845Vn6OTb/P/I68iYOfwGv+JOmRNHBfsV5ujA1LqM4eKDoNvXyDqItTxYX/DC9irKBlIhkKGPtFw1JDiMeS7CqWqySPZcKGHH/JHGgIpb6bCl1O0LmT57yCOqoI5UcU0YKjPXmFjMm0ZQ4NIVdGBdZRi9WrjLxJNMY1Yr4dYeuNxWApl1ALHb+KDHrTV1owlriedJgSr4Cybu/9dFiWYAagsqAGVkkzaZTAuqD9ywKWMUG9dCO3u2zWpVzIhpW122utZlrHnTN+Bq2Mqrlnqh8CQ+0Mrq3Kc++q7eo6dlB3rLuh3abPVbbbI2mxBdhWdsZhid8cr0oy9F08q0k5FXSadiyL1mF5z51a8VsQOp3/LlodkBfzmzWf2bOrtfzr48k/1hupDaLa9rUbO+zlwndfaOCURAXRNaCBqBT2BncJakWfTzSYkmCEFr60RX0V8sKaHOltCBJ1tAAFYhHaVVbig3jxp0IBADs=" >
<div id="brush"></div>
<ul id="samples">
<li>
<span class="sample" id="solidColor"></span>
<div class="sampleLabel">solidColor</div>
<div class="sampleCode" id="solidColorCode">rgb(0, 0, 0)</div>
</li>
<li>
<span class="sample" id="alphaColor"></span>
<div class="sampleLabel">alphaColor</div>
<div class="sampleCode" id="alphaColorCode">rgba(0, 0, 0, 0.00)</div>
</li>
<li>
<span class="sample" id="solidWeighted"></span>
<div class="sampleLabel">solidWeighted (with white)</div>
<div class="sampleCode" id="solidWeightedCode">rgb(0, 0, 0)</div>
</li>
</ul>
⚠️ দ্রষ্টব্য আমি Cross-Originযদি কোনও বাহ্যিক চিত্র বা আমি দীর্ঘতর ডেটা ইউআরআই ব্যবহার করার চেষ্টা করি তবে অনুমোদিত থেকে বড় যে উত্তরটি অন্তর্ভুক্ত করা হয় তা সমস্যাগুলি এড়াতে আমি একটি ছোট ডেটা ইউআরআই ব্যবহার করছি ।
Colors এই রঙগুলি অদ্ভুত দেখাচ্ছে, তাই না?
আপনি যদি কর্টারটিকে অস্ট্রিক আকারের সীমানার চারপাশে সরিয়ে ফেলেন তবে আপনি দেখতে পাবেন যে কখনও কখনও avgSolidColorলাল হয়, তবে যে পিক্সেলটি আপনি নমুনা দিচ্ছেন তা সাদা দেখাচ্ছে। কারণ এটি Rযে পিক্সেলের উপাদানগুলি বেশি হতে পারে, তবুও আলফা চ্যানেলটি কম, তাই রঙটি আসলে লাল রঙের প্রায় স্বচ্ছ ছায়ায়, তবেavgSolidColor উপেক্ষা করে।
অন্যদিকে, avgAlphaColorগোলাপী দেখায়। ঠিক আছে, এটি সত্য নয়, এটি কেবল গোলাপী দেখাচ্ছে কারণ আমরা এখন আলফা চ্যানেলটি ব্যবহার করছি, এটি এটিকে স্বল্পস্বামী করে তোলে এবং আমাদের পৃষ্ঠার পটভূমি দেখতে দেয় যা এই ক্ষেত্রে সাদা।
🎨 আলফা-ভারিত রঙ
তারপরে, আমরা এটি ঠিক করতে কী করতে পারি? ঠিক আছে, দেখা যাচ্ছে যে আমাদের নতুন নমুনার উপাদানগুলি গণনা করার জন্য আমাদের কেবলমাত্র আলফা চ্যানেল এবং এর বিপরীতমুখী ব্যবহার করা দরকার, এক্ষেত্রে এটি সাদা দিয়ে মার্জ করা, কারণ এটি আমরা পটভূমি হিসাবে ব্যবহার করি use
এর অর্থ হ'ল যদি পিক্সেল থাকে তবে অন্তর R, G, B, Aকোথায় Aথাকে [0, 1], আমরা আলফা চ্যানেলের বিপরীত iAএবং ওজনিত নমুনার উপাদানগুলি এইভাবে গণনা করব :
const iA = 1 - A;
const wR = (R * A + 255 * iA) | 0;
const wG = (G * A + 255 * iA) | 0;
const wB = (B * A + 255 * iA) | 0;
পিক্সেলটি আরও স্বচ্ছ ( A0 এর কাছাকাছি), হালকা রঙটি নোট করুন ।