এইচটিএমএল 5 ক্যানভাসে একক পিক্সেল সেট করার সর্বোত্তম উপায় কী?


184

এইচটিএমএল 5 ক্যানভাসের স্পষ্টভাবে একক পিক্সেল সেট করার কোনও পদ্ধতি নেই।

খুব সংক্ষিপ্ত রেখা ব্যবহার করে পিক্সেল সেট করা সম্ভব হতে পারে তবে অ্যান্টিয়ালাইজিং এবং লাইন ক্যাপগুলি হস্তক্ষেপ করতে পারে।

অন্য উপায় হতে পারে একটি ছোট ImageDataঅবজেক্ট তৈরি করা এবং ব্যবহার করা:

context.putImageData(data, x, y)

এটি জায়গায় রাখা।

কেউ কি এটির একটি দক্ষ এবং নির্ভরযোগ্য উপায় বর্ণনা করতে পারেন?

উত্তর:


292

দুটি সেরা প্রতিযোগী রয়েছে:

  1. একটি 1 × 1 চিত্রের ডেটা তৈরি করুন, রঙটি সেট করুন এবং putImageDataঅবস্থানটিতে:

    var id = myContext.createImageData(1,1); // only do this once per page
    var d  = id.data;                        // only do this once per page
    d[0]   = r;
    d[1]   = g;
    d[2]   = b;
    d[3]   = a;
    myContext.putImageData( id, x, y );     
    
  2. fillRect()পিক্সেল আঁকতে ব্যবহার করুন (কোনও এলিয়াসিং সমস্যা থাকা উচিত নয়):

    ctx.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")";
    ctx.fillRect( x, y, 1, 1 );
    

আপনি এখানে এগুলির গতি পরীক্ষা করতে পারেন: http://jsperf.com/setting-canvas-pixel/9 বা এখানে https://www.measurethat.net/Benchmark/Show/1664/1

আপনি সর্বোচ্চ গতির জন্য যত্নশীল ব্রাউজারগুলির বিরুদ্ধে পরীক্ষা করার পরামর্শ দিচ্ছি। জুলাই 2017 পর্যন্ত, fillRect()ফায়ারফক্স v54 এবং Chrome v59 (Win7x64) এ 5-6 × দ্রুত।

অন্যান্য, সিলিয়ার বিকল্পগুলি হ'ল:

  • getImageData()/putImageData()পুরো ক্যানভাস ব্যবহার করে; এটি অন্যান্য বিকল্পগুলির তুলনায় প্রায় 100। ধীর।

  • ডেটা ইউআরএল এবং drawImage()এটি দেখানোর জন্য ব্যবহার করে একটি কাস্টম চিত্র তৈরি করা:

    var img = new Image;
    img.src = "data:image/png;base64," + myPNGEncoder(r,g,b,a);
    // Writing the PNGEncoder is left as an exercise for the reader
    
  • আপনি চান সমস্ত পিক্সেল ভরা অন্য ইমগ বা ক্যানভাস তৈরি করা এবং drawImage()আপনি যে পিক্সেলটি চান তা ব্লিট করতে ব্যবহার করুন । এটি সম্ভবত খুব দ্রুত হবে তবে আপনার সীমাবদ্ধতা রয়েছে যা আপনার প্রয়োজনীয় পিক্সেলগুলি প্রাক-গণনা করতে হবে।

নোট করুন যে আমার পরীক্ষাগুলি ক্যানভাস প্রসঙ্গে সংরক্ষণ এবং পুনরুদ্ধার করার চেষ্টা করে না fillStyle; এই fillRect()কর্মক্ষমতা হ্রাস করবে । এছাড়াও নোট করুন যে আমি একটি পরিষ্কার স্লেট দিয়ে শুরু করছি না বা প্রতিটি পরীক্ষার জন্য ঠিক একই পিক্সেলের সেট সেট করছি।


2
আমি যদি বাগ রিপোর্ট ফাইল করার জন্য পারতাম তবে আমি আপনাকে আরও একটি +10 দিই! :)
Alnitak

51
মনে রাখবেন যে আমার জিপিইউ এবং গ্রাফিক্স ড্রাইভারগুলির সাথে আমার মেশিনে, fillRect()অর্ধ-সাম্প্রতিকটি Chromev24 এ 1x1 পুটিমেগডেটার চেয়ে প্রায় 10x দ্রুত হয়ে গেছে। সুতরাং ... যদি গতি সমালোচনা হয় এবং আপনি যদি আপনার টার্গেট শ্রোতাদের জানেন তবে একটি পুরানো উত্তরের শব্দটি (এমনকি আমারও) গ্রহণ করবেন না। পরিবর্তে: পরীক্ষা!
ফোগজ

3
উত্তর আপডেট করুন। ভরাট পদ্ধতিটি আধুনিক ব্রাউজারগুলিতে আরও দ্রুত।
বাজি

10
"পিএনজিএনকোডারটি লেখা পাঠকের পক্ষে অনুশীলন হিসাবে ছেড়ে গেছে" আমাকে উচ্চস্বরে হাসতে বাধ্য করে।
পাস্কাল গণায়

2
কেন আমি উত্থিত সমস্ত দুর্দান্ত ক্যানভাস উত্তরগুলি আপনার দ্বারা হয়ে থাকে? :)
ডোমিনো

18

একটি পদ্ধতি যা উল্লেখ করা হয়নি তা হ'ল getImageData এবং তারপরে putImageData ব্যবহার করা।
এই পদ্ধতিটি যখন আপনি একবারে অনেকগুলি আঁকতে চান দ্রুত হয় তখন এর জন্য ভাল।
http://next.plnkr.co/edit/mfNyalsAR2MWkccr

  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  var canvasWidth = canvas.width;
  var canvasHeight = canvas.height;
  ctx.clearRect(0, 0, canvasWidth, canvasHeight);
  var id = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
  var pixels = id.data;

    var x = Math.floor(Math.random() * canvasWidth);
    var y = Math.floor(Math.random() * canvasHeight);
    var r = Math.floor(Math.random() * 256);
    var g = Math.floor(Math.random() * 256);
    var b = Math.floor(Math.random() * 256);
    var off = (y * id.width + x) * 4;
    pixels[off] = r;
    pixels[off + 1] = g;
    pixels[off + 2] = b;
    pixels[off + 3] = 255;

  ctx.putImageData(id, 0, 0);

13
@ অ্যালনিটাক আপনার মন পড়তে না পারার জন্য আমাকে নীগ্রাহী দেওয়া কম .. আমি করেছি এবং তারপরে আরও কার্যকর উপায়টি মনে করেছি, তাই এটি ভাগ করে নেওয়া।
PAEz

গ্রাফিক্স ডেমো যেখানে প্রতিটি পিক্সেল গণনা করা হয় বা অনুরূপ, অনেক পিক্সেল পোকার সময় এটি একটি বোধগম্য পদ্ধতি। এটি প্রতিটি পিক্সেলের জন্য ফিলরেট ব্যবহারের চেয়ে দশগুণ বেশি।
স্যাম ওয়াটকিন্স

হ্যাঁ, এটি সর্বদা আমাকে ধমক দেয় যে ব্যতীত উত্তর বলে যে এই পদ্ধতিটি অন্যান্য পদ্ধতির চেয়ে 100x ধীর। এটি যদি আপনার পরিকল্পনার 1000 এরও কম হয় তবে এটি সত্য হতে পারে তবে সেখান থেকে এই পদ্ধতিটি জিততে শুরু করে এবং পরে অন্য পদ্ধতিগুলি জবাই করে। এখানে একটি পরীক্ষা ক্ষেত্রে .... এর measurethat.net/Benchmarks/Show/8386/0/...
Páez

17

আমি বিবেচনা করি নি fillRect(), কিন্তু উত্তরগুলি আমাকে এর বিরুদ্ধে মানদণ্ডে উত্সাহিত করেছিল putImage()

একটি (পুরানো) ম্যাকবুক প্রোতে Chrome 9.0.597.84 এর সাথে ক্রম 9.0.597.84 সহ এলোমেলোভাবে রঙিন পিক্সেল স্থাপন করা 100 মিমি সহ কম putImage()ব্যবহার করে তবে প্রায় 900 মিমি ব্যবহার করে fillRect()। ( Http://pastebin.com/4ijVKJcC এ বেঞ্চমার্ক কোড )।

পরিবর্তে যদি আমি লুপগুলির বাইরে একটি একক রঙ চয়ন করি এবং কেবল সেই রঙটি এলোমেলো স্থানে প্লট করি putImage()তবে এর জন্য 59ms বনাম 102ms লাগে fillRect()

মনে হচ্ছে rgb(...)সিনট্যাক্সে সিএসএস বর্ণের স্পেসিফিকেশন উত্পন্ন এবং পার্স করার ওভারহেড বেশিরভাগ পার্থক্যের জন্য দায়ী।

ImageDataঅন্যদিকে কাঁচা আরজিবি মানগুলি সরাসরি একটি ব্লকে রেখে দেওয়ার জন্য কোনও স্ট্রিং হ্যান্ডলিং বা বিশ্লেষণের প্রয়োজন নেই।


2
আমি একটি প্লাঙ্কার যুক্ত করেছি যেখানে আপনি একটি বোতামে ক্লিক করতে পারেন এবং প্রতিটি পদ্ধতি (পুতাইমেজেশন, ফিলারেক্ট) এবং অতিরিক্তভাবে লাইনটো পদ্ধতি পরীক্ষা করতে পারেন। এটি দেখায় যে পুতিমেজ এবং ফিলরেক্ট সময়ে খুব কাছাকাছি থাকলেও লাইনটো অত্যন্ত ধীর। এটি এখানে দেখুন: plnkr.co/edit/tww6e1VY2OCVY4c4ECy3?p= পূর্বরূপ এটি আপনার দুর্দান্ত পেস্টবিন কোডের উপর ভিত্তি করে। ধন্যবাদ।
রাদদেবাস

এই প্লাঙ্ককারের জন্য, আমি দেখতে পাচ্ছি যে ফিলিমেট ফিলারেক্টের (সাম্প্রতিক ক্রোম on৩ এ) তুলনায় কিছুটা ধীরে ধীরে, তবে আমি লাইনটো চেষ্টা করার পরে, পুতিমেজ ফিলারেক্টের তুলনায় উল্লেখযোগ্যভাবে দ্রুত is কোনওভাবে তারা হস্তক্ষেপ করছে বলে মনে হচ্ছে।
mlepage

13
function setPixel(imageData, x, y, r, g, b, a) {
    var index = 4 * (x + y * imageData.width);
    imageData.data[index+0] = r;
    imageData.data[index+1] = g;
    imageData.data[index+2] = b;
    imageData.data[index+3] = a;
}

var সূচক = (x + y * imageData.width) * 4;
ব্যবহারকারীর 889030

1
putImageData() সেই ফাংশনটির পরে ফোন করা উচিত বা প্রসঙ্গটি রেফারেন্স দ্বারা আপডেট হবে?
লুকাস সোসা

7

যেহেতু বিভিন্ন ব্রাউজারগুলি বিভিন্ন পদ্ধতির পছন্দ করে বলে মনে হচ্ছে, সম্ভবত লোডিং প্রক্রিয়াটির অংশ হিসাবে তিনটি পদ্ধতির সাথে একটি ছোট পরীক্ষা করে নেওয়া ভাল লাগবে যে কোনটি ব্যবহার করা ভাল এবং তা অ্যাপ্লিকেশন জুড়েই ব্যবহার করা ভাল?


5

এটি অদ্ভুত বলে মনে হয় তবে এইচটিএমএল 5 অঙ্কন লাইন, বৃত্ত, আয়তক্ষেত্র এবং অন্যান্য অনেকগুলি মৌলিক আকারগুলিকে সমর্থন করে, এটিতে মূল বিন্দু আঁকার উপযুক্ত কিছু নেই। এটি করার একমাত্র উপায় হ'ল আপনার যা কিছু আছে তার সাথে বিন্দুটি অনুকরণ করা।

সুতরাং মূলত 3 টি সম্ভাব্য সমাধান রয়েছে:

  • একটি লাইন হিসাবে বিন্দু আঁকুন
  • বহুভুজ হিসাবে বিন্দু আঁকুন
  • একটি বৃত্ত হিসাবে বিন্দু আঁকুন

তাদের প্রত্যেকের নিজস্ব ত্রুটি রয়েছে


লাইন

function point(x, y, canvas){
  canvas.beginPath();
  canvas.moveTo(x, y);
  canvas.lineTo(x+1, y+1);
  canvas.stroke();
}

মনে রাখবেন যে আমরা দক্ষিণ-পূর্ব দিকের দিকে আঁকছি, এবং এটি যদি প্রান্ত হয় তবে সমস্যা হতে পারে। তবে আপনি অন্য কোনও দিকেও আঁকতে পারেন।


আয়তক্ষেত্র

function point(x, y, canvas){
  canvas.strokeRect(x,y,1,1);
}

বা দ্রুততরভাবে ফিলারেক্ট ব্যবহার করে কারণ রেন্ডার ইঞ্জিন কেবল একটি পিক্সেল পূরণ করবে।

function point(x, y, canvas){
  canvas.fillRect(x,y,1,1);
}

বৃত্ত


চেনাশোনাগুলির সাথে অন্যতম সমস্যা হ'ল কোনও ইঞ্জিনকে রেন্ডার করা শক্ত

function point(x, y, canvas){
  canvas.beginPath();
  canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
  canvas.stroke();
}

আয়তক্ষেত্রের মতো একই ধারণাটি আপনি পূরণের মাধ্যমে অর্জন করতে পারেন।

function point(x, y, canvas){
  canvas.beginPath();
  canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
  canvas.fill();
}

এই সমস্ত সমাধানে সমস্যা:

  • আপনি যে পয়েন্টগুলি আঁকতে যাচ্ছেন তার উপর নজর রাখা শক্ত।
  • আপনি যখন জুম করবেন তখন দেখতে দেখতে কুশ্রী লাগবে।

আপনি যদি ভাবছেন, " বিন্দু আঁকার সর্বোত্তম উপায় কোনটি ? ", আমি পূর্ণ আয়তক্ষেত্র নিয়ে যাব। তুলনা পরীক্ষার সাথে আপনি এখানে আমার jsperf দেখতে পারেন ।


দক্ষিণ-পূর্ব দিক? কি?
লোগানডার্ক

4

একটি আয়তক্ষেত্র সম্পর্কে কি? এটি একটি ImageDataঅবজেক্ট তৈরির চেয়ে আরও দক্ষ হতে হবে ।


3
আপনি এত মনে চাই, এবং এটি একটি একক পিক্সেলের জন্য হতে পারে, কিন্তু ইমেজ তথ্য যদি আপনি প্রাক তৈরি এবং 1 পিক্সেল সেট এবং তারপর ব্যবহার putImageDataএটা 10x চেয়ে দ্রুত fillRectChrome এ। (আরও তথ্যের জন্য আমার উত্তর দেখুন।)
Phrogz

2

Sdleihssirhc এর মতো একটি আয়তক্ষেত্র আঁকুন!

ctx.fillRect (10, 10, 1, 1);

^ - x: 10, y: 10 এ 1x1 আয়তক্ষেত্র আঁকতে হবে


1

হুম, আপনি কেবল 1 পিক্সেলের দৈর্ঘ্য সহ 1 পিক্সেল প্রশস্ত লাইন তৈরি করতে এবং এটি একটি একা অক্ষের সাথে দিকটি সরানোতে সক্ষম করতে পারেন।

            ctx.beginPath();
            ctx.lineWidth = 1; // one pixel wide
            ctx.strokeStyle = rgba(...);
            ctx.moveTo(50,25); // positioned at 50,25
            ctx.lineTo(51,25); // one pixel long
            ctx.stroke();

1
আমি ফিলারেক্ট, পুতআইমেজ এবং লাইনটো হিসাবে পিক্সেল ড্র প্রয়োগ করেছি এবং একটি প্লামকার তৈরি করেছি: plnkr.co/edit/tww6e1VY2OCVY4c4ECy3?p= পূর্বরূপ এটি পরীক্ষা করে দেখুন, কারণ লাইনটো দ্রুততর ধীর হয় is 0.25 সেকেন্ডে 100,000 পয়েন্ট ডাব্লু অন্যান্য 2 পদ্ধতিগুলি করতে পারে তবে লাইনটো সহ 10,000 পয়েন্ট 5 সেকেন্ড সময় নেয়।
রাদেবাস

1
ঠিক আছে, আমি একটি ভুল করেছি এবং আমি লুপটি বন্ধ করতে চাই। লাইনটো কোডটি একটি অনুপস্থিত ছিল - অত্যন্ত গুরুত্বপূর্ণ লাইন - যা নিম্নলিখিতগুলির মতো দেখাচ্ছে: ctx.beginPath (); আমি প্লঙ্কার আপডেট করেছি (আমার অন্যান্য মন্তব্য থেকে লিঙ্কে) এবং যুক্ত করেছি যে একটি লাইন এখন লাইনটো পদ্ধতিতে 0.5 সেকেন্ডে গড়ে 100,000 জেনারেট করে। বেশ চমৎকার. সুতরাং আপনি যদি নিজের উত্তরটি সম্পাদনা করেন এবং সেই কোডটি আপনার কোডে যুক্ত করেন (ctx.lineWidth লাইনের আগে) আমি আপনাকে আপোভেট করব। আমি আশা করি আপনি এটি আকর্ষণীয় পেয়েছেন এবং আমি আমার মূল বগি কোডের জন্য ক্ষমা চাইছি।
রাদেবাস

1

ফ্রেোগজ খুব পুঙ্খানুপুঙ্খ উত্তর সম্পূর্ণ করতে, fillRect()এবং এর মধ্যে একটি গুরুতর পার্থক্য রয়েছে putImageData()
প্রথম ব্যবহারসমূহ প্রসঙ্গ আঁকা উপর দ্বারা যোগ , একটি আয়তক্ষেত্র (একটি পিক্সেল) ব্যবহার fillStyle আলফা মান এবং প্রাসঙ্গিক globalAlpha এবং রূপান্তর ম্যাট্রিক্স , লাইন ক্যাপ ইত্যাদি ..
দ্বিতীয় প্রতিস্থাপন একটি সম্পূর্ণ পিক্সেল সেট (হয়তো এক, কিন্তু কেন ?)
আপনি jsperf এ দেখতে পাচ্ছেন ফলাফলটি ভিন্ন


কেউ একবারে একটি পিক্সেল সেট করতে চায় না (যার অর্থ এটি স্ক্রিনে আঁকানো)। সে কারণেই এটি করার জন্য কোনও নির্দিষ্ট এপিআই নেই (এবং যথাযথভাবে)।
পারফরম্যান্স অনুসারে, যদি লক্ষ্যটি কোনও ছবি তৈরি করা হয় (উদাহরণস্বরূপ একটি রে-ট্রেসিং সফ্টওয়্যার), আপনি সর্বদা প্রাপ্ত একটি অ্যারে ব্যবহার করতে চান getImageData()যা একটি অনুকূলিত ইউিন্ট 8 অ্যারে ray তারপরে আপনি putImageData()ওএনএসইএল বা কয়েক সেকেন্ডে কয়েকবার কল ব্যবহার করে setTimeout/seTInterval


আমার একটি কেস হয়েছে যেখানে আমি একটি ছবিতে 100 কে ব্লক রাখতে চেয়েছিলাম, তবে 1: 1 পিক্সেল স্কেলে নয়। ব্যবহার fillRectকরা বেদনাদায়ক কারণ ক্রোমের এইচ / ডাব্লু ত্বরণটি যে জিপিইউতে লাগবে তার জন্য পৃথক কলগুলি মোকাবেলা করতে পারে না। আমি 1: 1 এ পিক্সেল ডেটা ব্যবহার করে শেষ করেছি এবং তারপরে কাঙ্ক্ষিত আউটপুট পেতে সিএসএস স্কেলিং ব্যবহার করব। এটি কুৎসিত :(
অলনিটক

ফায়ারফক্স 42 এ আপনার লিঙ্কযুক্ত বেঞ্চমার্ক চালানো আমি কেবল 168 অপস / সেকেন্ডের জন্য get/putImageDataপেয়েছি, তবে 194,893 এর জন্য fillRect1x1 image data125,102 অপস / সেকেন্ড তাই fillRectফায়ারফক্সে জিতেছে। সুতরাং 2012 এবং আজকের মধ্যে জিনিসগুলি অনেকটা পরিবর্তিত হয়েছে। সর্বদা হিসাবে, কখনও পুরানো মানদণ্ডের ফলাফলের উপর নির্ভর করবেন না।
মক্কি

12
আমি একবারে একটি পিক্সেল সেট করতে চাই। আমি এই প্রশ্নের শিরোনাম দ্বারা অনুমান করছি যে অন্যান্য লোকেরাও এটি করে
চশমনি

1

দ্রুত এইচটিএমএল ডেমো কোড: এসএফএমএল সি ++ গ্রাফিক্স লাইব্রেরি সম্পর্কে আমি যা জানি তার ভিত্তিতে:

এটি ইউটিএফ -8 এনকোডিং সহ একটি HTML ফাইল হিসাবে সংরক্ষণ করুন এবং এটি চালান। অশোধনকারী নির্দ্বিধায়, আমি ঠিক জাপানি ভেরিয়েবলগুলি ব্যবহার করতে পছন্দ করি কারণ তারা সংক্ষিপ্ত এবং বেশি জায়গা নেয় না

কদাচিৎ আপনি একটি স্বেচ্ছাচারিত পিক্সেল সেট করতে এবং এটি স্ক্রিনে প্রদর্শন করতে চান। সুতরাং ব্যবহার করুন

PutPix(x,y, r,g,b,a) 

ব্যাক-বাফারে অসংখ্য স্বেচ্ছাসেবক পিক্সেল আঁকার পদ্ধতি। (সস্তা কল)

তারপরে যখন দেখানোর জন্য প্রস্তুত হবে তখন ফোন করুন

Apply() 

পরিবর্তনগুলি প্রদর্শন করার পদ্ধতি। (ব্যয়বহুল কল)

সম্পূর্ণ .এইচটিএমএল ফাইল কোড নীচে:

<!DOCTYPE HTML >
<html lang="en">
<head>
    <title> back-buffer demo </title>
</head>
<body>

</body>

<script>
//Main function to execute once 
//all script is loaded:
function main(){

    //Create a canvas:
    var canvas;
    canvas = attachCanvasToDom();

    //Do the pixel setting test:
    var test_type = FAST_TEST;
    backBufferTest(canvas, test_type);
}

//Constants:
var SLOW_TEST = 1;
var FAST_TEST = 2;


function attachCanvasToDom(){
    //Canvas Creation:
    //cccccccccccccccccccccccccccccccccccccccccc//
    //Create Canvas and append to body:
    var can = document.createElement('canvas');
    document.body.appendChild(can);

    //Make canvas non-zero in size, 
    //so we can see it:
    can.width = 800;
    can.height= 600;

    //Get the context, fill canvas to get visual:
    var ctx = can.getContext("2d");
    ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
    ctx.fillRect(0,0,can.width-1, can.height-1);
    //cccccccccccccccccccccccccccccccccccccccccc//

    //Return the canvas that was created:
    return can;
}

//THIS OBJECT IS SLOOOOOWW!
// 筆 == "pen"
//T筆 == "Type:Pen"
function T筆(canvas){


    //Publicly Exposed Functions
    //PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE//
    this.PutPix = _putPix;
    //PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE//

    if(!canvas){
        throw("[NilCanvasGivenToPenConstruct]");
    }

    var _ctx = canvas.getContext("2d");

    //Pixel Setting Test:
    // only do this once per page
    //絵  =="image"
    //資  =="data"
    //絵資=="image data"
    //筆  =="pen"
    var _絵資 = _ctx.createImageData(1,1); 
    // only do this once per page
    var _  = _絵資.data;   


    function _putPix(x,y,  r,g,b,a){
        _筆[0]   = r;
        _筆[1]   = g;
        _筆[2]   = b;
        _筆[3]   = a;
        _ctx.putImageData( _絵資, x, y );  
    }
}

//Back-buffer object, for fast pixel setting:
//尻 =="butt,rear" using to mean "back-buffer"
//T尻=="type: back-buffer"
function T尻(canvas){

    //Publicly Exposed Functions
    //PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE//
    this.PutPix = _putPix;
    this.Apply  = _apply;
    //PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE//

    if(!canvas){
        throw("[NilCanvasGivenToPenConstruct]");
    }

    var _can = canvas;
    var _ctx = canvas.getContext("2d");

    //Pixel Setting Test:
    // only do this once per page
    //絵  =="image"
    //資  =="data"
    //絵資=="image data"
    //筆  =="pen"
    var _w = _can.width;
    var _h = _can.height;
    var _絵資 = _ctx.createImageData(_w,_h); 
    // only do this once per page
    var _  = _絵資.data;   


    function _putPix(x,y,  r,g,b,a){

        //Convert XY to index:
        var dex = ( (y*4) *_w) + (x*4);

        _筆[dex+0]   = r;
        _筆[dex+1]   = g;
        _筆[dex+2]   = b;
        _筆[dex+3]   = a;

    }

    function _apply(){
        _ctx.putImageData( _絵資, 0,0 );  
    }

}

function backBufferTest(canvas_input, test_type){
    var can = canvas_input; //shorthand var.

    if(test_type==SLOW_TEST){
        var t = new T筆( can );

        //Iterate over entire canvas, 
        //and set pixels:
        var x0 = 0;
        var x1 = can.width - 1;

        var y0 = 0;
        var y1 = can.height -1;

        for(var x = x0; x <= x1; x++){
        for(var y = y0; y <= y1; y++){
            t筆.PutPix(
                x,y, 
                x%256, y%256,(x+y)%256, 255
            );
        }}//next X/Y

    }else
    if(test_type==FAST_TEST){
        var t = new T尻( can );

        //Iterate over entire canvas, 
        //and set pixels:
        var x0 = 0;
        var x1 = can.width - 1;

        var y0 = 0;
        var y1 = can.height -1;

        for(var x = x0; x <= x1; x++){
        for(var y = y0; y <= y1; y++){
            t尻.PutPix(
                x,y, 
                x%256, y%256,(x+y)%256, 255
            );
        }}//next X/Y

        //When done setting arbitrary pixels,
        //use the apply method to show them 
        //on screen:
        t尻.Apply();

    }
}


main();
</script>
</html>


-1

হাত এবং পুট পিক্সেল (পিপি) ফাংশন (ES6) এর প্রস্তাব ( এখানে পঠন পিক্সেল ):

let pp= ((s='.myCanvas',c=document.querySelector(s),ctx=c.getContext('2d'),id=ctx.createImageData(1,1)) => (x,y,r=0,g=0,b=0,a=255)=>(id.data.set([r,g,b,a]),ctx.putImageData(id, x, y),c))()

pp(10,30,0,0,255,255);    // x,y,r,g,b,a ; return canvas object

এই ফাংশনটির putImageDataআরম্ভের অংশ রয়েছে (প্রথম দীর্ঘ রেখা)। শুরুতে পরিবর্তে s='.myCanvas'আপনি আপনার ক্যানভাসে সিএসএস নির্বাচনকারী ব্যবহার করুন।

আমি তোমাকে চাই 0-1 থেকে মান পরামিতি স্বাভাবিক করার জন্য আপনাকে ডিফল্ট মান পরিবর্তন করা উচিত a=255করতে a=1এবং লাইন: id.data.set([r,g,b,a]),ctx.putImageData(id, x, y)থেকে id.data.set([r*255,g*255,b*255,a*255]),ctx.putImageData(id, x*c.width, y*c.height)

উপরের সহজ কোডটি অ্যাড-হক পরীক্ষা গ্রাফিক্স অ্যালগরিদম বা ধারণার প্রমাণ তৈরি করা ভাল, তবে কোডটি পাঠযোগ্য এবং স্পষ্ট হওয়া উচিত এমন উত্পাদনে ব্যবহার করা ভাল নয়।


1
দরিদ্র ইংলিশ এবং একটি বিশৃঙ্খল ওয়ান লাইনারকে ডাউন-ভোট দিয়েছে।
জাভিয়েয়ার

1
@ এক্সভিয়ার - ইংরেজি আমার মাতৃভাষা নয় এবং আমি ফোরগিন ভাষা শিখতে ভাল নই, তবে আপনি আমার উত্তরটি সম্পাদনা করতে এবং ভাষা বাগগুলি ঠিক করতে পারেন (এটি আপনার কাছ থেকে ইতিবাচক অবদান হবে)। আমি এই ওয়ান-লাইনারটি রেখেছি কারণ এটি সহজ এবং সহজেই ব্যবহারযোগ্য - এবং শিক্ষার্থীদের জন্য কিছু গ্রাফিক অ্যালগরিদমগুলি পরীক্ষা করা উদাহরণস্বরূপ ভাল হতে পারে, তবে কোডটি পাঠযোগ্য এবং স্পষ্ট হওয়া উচিত যেখানে উত্পাদনে এটি ব্যবহার করা ভাল সমাধান নয়।
কামিল কিয়েসজেউস্কি

3
@ কামিলকিএকজেউসকি কোডটি পাঠযোগ্য এবং স্পষ্ট হওয়া শিক্ষার্থীদের পক্ষে ঠিক ততটা গুরুত্বপূর্ণ, এটি পেশাদারদের জন্য।
লোগান পিকআপ

-2

putImageDataসম্ভবত দেশীয় তুলনায় দ্রুত fillRect। আমি এটি মনে করি কারণ পঞ্চম প্যারামিটারে ভিন্ন ভিন্ন উপায় থাকতে পারে (আয়তক্ষেত্রের রঙ), এমন স্ট্রিং ব্যবহার করে যা ব্যাখ্যা করা উচিত।

মনে করুন আপনি এটি করছেন:

context.fillRect(x, y, 1, 1, "#fff")
context.fillRect(x, y, 1, 1, "rgba(255, 255, 255, 0.5)")`
context.fillRect(x, y, 1, 1, "rgb(255,255,255)")`
context.fillRect(x, y, 1, 1, "blue")`

সুতরাং, লাইন

context.fillRect(x, y, 1, 1, "rgba(255, 255, 255, 0.5)")`

সকলের মধ্যে সবচেয়ে ভারী। fillRectকলের পঞ্চম আর্গুমেন্টটি কিছুটা দীর্ঘ স্ট্রিং।


1
কোন ব্রাউজার সমর্থন করে 5 তম আর্গুমেন্ট হিসাবে কোনও রঙ পাস? ক্রোমের জন্য আমাকে context.fillStyle = ...পরিবর্তে ব্যবহার করতে হয়েছিল। বিকাশকারী.মোজিলা.আর.ইন-
ইউএস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.