আমি কি এইচটিএমএল <ক্যানভাস> এলিমেন্টে এন্টিএলিজিং বন্ধ করতে পারি?


88

আমি সাথে খেলা করছি <canvas> এলিমেন্ট, অঙ্কন লাইন এবং এই জাতীয় ।

আমি লক্ষ্য করেছি যে আমার তির্যক রেখাগুলি অ্যান্টিয়ালাইজড। আমি যা করছি তার জন্য আমি জগি চেহারা পছন্দ করব - এই বৈশিষ্ট্যটি বন্ধ করার কোনও উপায় আছে কি?


আমি মনে করি এটি বরং ব্রাউজার সম্পর্কিত। আপনি কোন সফ্টওয়্যারটি ব্যবহার করেন সে সম্পর্কে কিছু অতিরিক্ত তথ্য সহায়ক হতে পারে।
তোমালাক

আমি ক্রস ব্রাউজার পদ্ধতিটি পছন্দ করতাম তবে যে পদ্ধতিটি কোনও একক ব্রাউজারে কাজ করে তা এখনও আমার কাছে আকর্ষণীয় হতে পারে
ব্লারগার্ড

আমি কেবল দেখতে চেয়েছিলাম যে এই বিষয়ে এখনও কোনও পরিবর্তন হয়েছে কিনা?
vtern3


এই কোনো আপডেট আছে কি?
রোল্যান্ড

উত্তর:


64

চিত্রের জন্য এখন আছে ।context.imageSmoothingEnabled= false

তবে, লাইন অঙ্কনকে স্পষ্টভাবে নিয়ন্ত্রণ করে এমন কিছুই নেই। আপনার নিজের লাইনগুলি ( শক্ত উপায় ) ব্যবহার করে getImageDataএবং আঁকার দরকার হতে পারে putImageData


4
আমি একটি জাভাস্ক্রিপ্ট লাইন অ্যালগরিদমের অভিনয় সম্পর্কে অবাক হয়েছি .. ব্রেসেনহ্যামকে কিছুটা সময় দিতে পারি।
ব্লারগবার্ড

ব্রাউজার বিক্রেতারা ইদানীং নতুন সুপার-ফাস্ট জেএস ইঞ্জিনগুলি টাউট করছেন, সুতরাং শেষ পর্যন্ত এটির জন্য একটি ভাল ব্যবহার হবে।
কর্নেল

4
এটি কি সত্যিই কাজ করে? আমি ব্যবহার করে একটি লাইন অঙ্কন করছি putImageData তবে এটি এখনও নিকটবর্তী পিক্সেল শঙ্কার আলিয়াসিং করে।
পেসারিয়ার

যদি আমি একটি ছোট ক্যানভাসে টানা হয় (ক্যাশে) এবং তারপরে সেই সেটিংটি বন্ধ করে অন্য কোনও ক্যানভাসে আঁকি, এটি কি ইচ্ছা মত কাজ করবে?
স্পার্ক

69

আপনার 1-pixelলাইনের স্থানাঙ্কগুলিতে পছন্দ করুন ctx.lineTo(10.5, 10.5)। বিন্দুকে কেন্দ্র করে একটি এক-পিক্সেল রেখা আঁকা (10, 10)মানে, যে এই 1থেকে যে অবস্থানে পৌছানোর এ পিক্সেল 9.5থেকে 10.5যা দুই লাইন যে পটে আকাঁ পেতে ফলাফল।

শুরুতে আপনার পুরো ক্যানভাসটিতে 0.5যদি আপনি প্রচুর এক-পিক্সেল লাইন পেয়ে থাকেন তবে যে অঙ্কনটি আপনি আঁকতে চান তা সর্বদা যুক্ত করতে হবে না এমন একটি দুর্দান্ত কৌশল alwaysctx.translate(0.5, 0.5)


হুম, এই কৌশলটি ব্যবহার করে অ্যান্টি-এলিয়জিং থেকে মুক্তি পেতে আমার একটি সমস্যা হচ্ছে। হতে পারে, আমি কিছু বুঝতে মিস করছি? আপনি কোথাও একটি উদাহরণ পোস্ট করতে আপত্তি করবেন?
জাভি

7
এটি অ্যান্টিয়ালাইজিং থেকে মুক্তি পাবে না, তবে এন্টিএলিয়েসড লাইনগুলি আরও ভাল দেখায় --- যেমন আপনি বিব্রতকর অনুভূমিক বা উল্লম্ব রেখাগুলি যে দুটি পিক্সেল পুরু যখন আপনি আসলে একটি পিক্সেল চেয়েছিলেন তা থেকে মুক্তি পান।
ডেভিড

4
@ পার্নেল: না, পিক্সেলের কোণগুলির মধ্যে রেখাগুলি আঁকা। যখন আপনার লাইনটি 1 পিক্সেল প্রশস্ত হবে, যা উভয় দিকের অর্ধ পিক্সেল প্রসারিত করবে
এরিক

+0.5 যুক্ত করা আমার পক্ষে কাজ করে তবে ctx.translate(0.5,0.5)তা করেনি। এফএফ 39.0
পাওলো বুয়েনো

আপনাকে অনেক ধন্যবাদ! আমি বিশ্বাস করতে পারি না যে পরিবর্তনের জন্য আমার কাছে আসল 1px লাইন আছে!
নিটোল Chunk,

24

এটি মজিলা ফায়ারফক্সে করা যেতে পারে। এটি আপনার কোডে যুক্ত করুন:

contextXYZ.mozImageSmoothingEnabled = false;

অপেরাতে এটি বর্তমানে বৈশিষ্ট্যের অনুরোধ, তবে আশা করি এটি শীঘ্রই যুক্ত হয়ে যাবে।


শীতল আপনার অবদানের জন্য +1 আমি আশ্চর্য হই যে এএকে অক্ষম করায় রেখাযুক্ত করা গতিবেগ হয়েছে
মারকাস্ক্লাস

7
ওপি অ্যান্টি-অ্যালিফ লাইনগুলি আন আনতে চায় তবে এটি কেবল চিত্রগুলিতে কাজ করে। প্রতি বৈশিষ্ট , এটা নির্ধারণ করে"whether pattern fills and the drawImage() method will attempt to smooth images if their pixels don't line up exactly with the display, when scaling images up"
rvighne

13

এটি অ্যান্টিয়াল ভেক্টর গ্রাফিক্স অবশ্যই আবশ্যক

আন্তঃসংখ্যক স্থানাঙ্ক (0.4, 0.4) জড়িত ভেক্টর গ্রাফিক্সের সঠিক প্লট করার জন্য অ্যান্টিয়ালাইজিং প্রয়োজন , যা খুব কম ক্লায়েন্টই করেন।

যখন অ-পূর্ণসংখ্যা স্থানাঙ্ক দেওয়া হয়, ক্যানভাসের দুটি বিকল্প থাকে:

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

পরবর্তী কৌশলটি স্থির গ্রাফিক্সের জন্য কাজ করবে, যদিও ছোট গ্রাফিক্সের জন্য (2 এর ব্যাসার্ধের একটি বৃত্ত) বক্ররেখা একটি মসৃণ বক্রতার পরিবর্তে পরিষ্কার পদক্ষেপগুলি প্রদর্শন করবে।

আসল সমস্যাটি হ'ল যখন গ্রাফিকগুলি অনুবাদ করা হয় (সরানো) - এক পিক্সেল এবং অন্যটির মধ্যে জাম্প হয় (১.6 => ২, ১.৪ => ১), এর অর্থ এই যে আকারের উত্স পিতামাতার ধারকের সাথে ঝাঁপিয়ে পড়তে পারে (ক্রমাগত স্থানান্তরিত হয়) 1 পিক্সেল উপরে / নীচে এবং বাম / ডান)।

কিছু টিপস

টিপ # 1 : আপনি ক্যানভাসকে স্কেল করে (বা শক্ত করে) অ্যান্টিয়ালাইজিংকে নরম করতে পারেন (এক্স দ্বারা বলুন) তারপরে নিজের জ্যামিতিতে রেকিপ্রোকাল স্কেল (1 / এক্স) প্রয়োগ করুন (ক্যানভাসটি ব্যবহার করছেন না)।

তুলনা (কোন স্কেলিং):

কয়েকটি আয়তক্ষেত্র

(ক্যানভাস স্কেল: 0.75; ম্যানুয়াল স্কেল: 1.33) সহ:

নরম প্রান্তের সাথে একই আয়তক্ষেত্রগুলি

এবং (ক্যানভাস স্কেল: 1.33; ম্যানুয়াল স্কেল: 0.75):

গাer় প্রান্তের সাথে একই আয়তক্ষেত্রগুলি

টিপ # 2 : যদি আপনার জাগতিক চেহারাটি আপনার পরে যা হয় তবে তা প্রতিটি আকৃতি কয়েকবার আঁকতে চেষ্টা করুন (মোছা না করে)। প্রতিটি অঙ্কনের সাথে সাথে অ্যান্টিঅ্যালাসিং পিক্সেল আরও গা .় হয়।

তুলনা করা. একবার আঁকার পরে:

কয়েকটি পথ

তিনবার আঁকার পরে:

একই পথ তবে গাer় এবং কোনও দৃশ্যমান অ্যান্টিঅ্যালিয়াসিং।


@ অ্যানোভাম নির্দ্বিধায় ক্লোন করতে এবং এতে খেলতে পারেন: github.com/Izhaki/gefri । সমস্ত চিত্রগুলি / ডেমো ফোল্ডারটির স্ক্রিনশট (টিপ # 2 এর জন্য কিছুটা সংশোধিত কোড সহ)। আমি নিশ্চিত যে আপনি অঙ্কিত পরিসংখ্যানগুলিতে পূর্ণসংখ্যার বৃত্তাকার পরিচয় করিয়ে দেওয়া সহজ পাবেন (আমার 4 মিনিট সময় নিয়েছে) এবং তারপরে প্রভাবটি দেখতে কেবল টানুন।
ইজ্জাকি

শুনে অবিশ্বাস্য মনে হতে পারে, কিন্তু হয় বিরল পরিস্থিতিতে যেখানে আপনি antialias বন্ধ পরিণত করতে চান। প্রকৃতপক্ষে, আমি কেবল একটি গেমটি প্রোগ্রাম করেছিলাম যেখানে লোকেরা অবশ্যই একটি ক্যানভাসে অঞ্চলগুলি আঁকতে পারে এবং আমার কেবল সেখানে 4 টি রঙ থাকতে হবে এবং অ্যান্টিয়ালিয়াসের কারণে আমি আটকেছি। প্যাটার্নটি তিনবার পুনরাবৃত্তি করা সমস্যার সমাধান করেনি (আমি ২০০ এ উঠেছি) এবং এখনও ভুল রঙের পিক্সেল রয়েছে।
আরনাউড

9

আমি কাস্টম লাইন অ্যালগরিদম যেমন ব্রেনহ্যামের লাইন অ্যালগরিদম ব্যবহার করে সমস্ত কিছু আঁকতাম। এই জাভাস্ক্রিপ্ট প্রয়োগ বাস্তবায়ন দেখুন: http://mebers.chello.at/easyfilter/canvas.html

আমি মনে করি এটি অবশ্যই আপনার সমস্যার সমাধান করবে।


4
হুবহু আমার যা প্রয়োজন, কেবলমাত্র আমি যোগ করব তা হল আপনার বাস্তবায়ন করা দরকার setPixel(x, y); আমি স্বীকৃত উত্তরটি এখানে ব্যবহার করেছি: stackoverflow.com/questions/4899799/…
টিনা ভল

8

আমি যুক্ত করতে চাই যে কোনও চিত্রকে ক্ষুদ্রতর করার সময় এবং ক্যানভাসে আঁকতে আমার সমস্যা হয়েছিল, এটি এখনও স্মুথিং ব্যবহার করছিল, যদিও এটি উপরে উঠে যাওয়ার সময় ব্যবহার করা হয়নি।

আমি এটি ব্যবহার করে সমাধান করেছি:

function setpixelated(context){
    context['imageSmoothingEnabled'] = false;       /* standard */
    context['mozImageSmoothingEnabled'] = false;    /* Firefox */
    context['oImageSmoothingEnabled'] = false;      /* Opera */
    context['webkitImageSmoothingEnabled'] = false; /* Safari */
    context['msImageSmoothingEnabled'] = false;     /* IE */
}

আপনি এই ফাংশনটি এভাবে ব্যবহার করতে পারেন:

var canvas = document.getElementById('mycanvas')
setpixelated(canvas.getContext('2d'))

এটি কারও পক্ষে কার্যকর is


প্রসঙ্গটি কেন না?
মার্টিজন শেফার

আমি আমার উত্তরটি লেখার সময় এটি কার্যকর হয়নি। এটা কি এখন কাজ করে?
এরি0o

4
এটি ঠিক একই জিনিসটি করেছে, জাভাস্ক্রিপ্ট লেখার ক্ষেত্রে ['নাম'] বা .জেক্ট.নাম সবসময়ই ছিল এবং সর্বদা একই থাকবে, কোনও বস্তু নামযুক্ত মানের (টিপলস) একটি সংকলন, যা কিছুটির মতো দেখা যায় হ্যাশ টেবিল, উভয় স্বরলিপি একইরূপে বিবেচিত হবে, আপনার কোডটি আগে কাজ করবে না এমন কোনও কারণ নেই, সবচেয়ে খারাপভাবে এটি এমন একটি মান নির্ধারণ করে যা কোনও প্রভাব ফেলেনি (কারণ এটি অন্য ব্রাউজারের উদ্দেশ্যে। একটি সাধারণ উদাহরণ: লিখুন আপত্তি = {এ: 123}; কনসোল.লগ (আপত্তি ['এ'] === আপত্তি.এ? "হ্যাঁ এটি সত্য": "না এটি নয়")
মার্টিজন শেফার

আমি ভেবেছিলাম আপনি কেন অন্য সমস্ত জিনিস কেন বোঝাতে চেয়েছিলেন, আমার মন্তব্যে আমি যা বোঝাতে চেয়েছিলাম তা হ'ল ব্রাউজারগুলির জন্য বিভিন্ন ধরণের সম্পত্তি প্রয়োজন।
এরি0o

অবশ্যই হ্যাঁ অবশ্যই :) আমি সিনট্যাক্সের কথা বলছিলাম, কোডের বৈধতা নিজেই নয় (এটি কাজ করে)
মার্টিজন শেফার

6
ctx.translate(0.5, 0.5);
ctx.lineWidth = .5;

এই কম্বো দিয়ে আমি সুন্দর 1px পাতলা রেখা আঁকতে পারি।


6
আপনার লাইনউইথকে .5 তে সেট করার দরকার নেই ... এটি (বা হওয়া উচিত) এটি অর্ধ বিবর্ধন করবে।
এএইডান

4

একটি খুব সীমিত কৌশল লক্ষ্য করুন। আপনি যদি 2 টি রঙের চিত্র তৈরি করতে চান তবে আপনি # 010101 # 000000 রঙের পটভূমিতে রঙের সাথে আপনার পছন্দ মতো কোনও আকার আঁকতে পারেন। এটি হয়ে গেলে, আপনি প্রতিটি পিক্সেলটি চিত্র.ডেটা.ডেটায় [] পরীক্ষা করতে পারেন এবং মান 0x00 নয় যা 0xFF এ সেট করতে পারেন:

imageData = context2d.getImageData (0, 0, g.width, g.height);
for (i = 0; i != imageData.data.length; i ++) {
    if (imageData.data[i] != 0x00)
        imageData.data[i] = 0xFF;
}
context2d.putImageData (imageData, 0, 0);

ফলাফলটি অ-অ্যান্টিএলিয়েসড কালো ও সাদা ছবি হবে। এটি নিখুঁত হবে না, যেহেতু কিছু antialiasing সংঘটিত হবে, তবে এই antialiasing খুব সীমাবদ্ধ হবে, আকৃতির রঙটি অনেকটা ব্যাকগ্রাউন্ডের বর্ণের মতো।


1

যারা এখনও উত্তর খুঁজছেন তাদের জন্য। এখানে আমার সমাধান।

ধরে নিচ্ছি চিত্রটি 1 চ্যানেল ধূসর। আমি স্রেফ ctx.stroke () এর পরে থ্রেশহোল্ড করেছি।

ctx.beginPath();
ctx.moveTo(some_x, some_y);
ctx.lineTo(some_x, some_y);
...
ctx.closePath();
ctx.fill();
ctx.stroke();

let image = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height)
for(let x=0; x < ctx.canvas.width; x++) {
  for(let y=0; y < ctx.canvas.height; y++) {
    if(image.data[x*image.height + y] < 128) {
      image.data[x*image.height + y] = 0;
    } else {
      image.data[x*image.height + y] = 255;
    }
  }
}

যদি আপনার চিত্র চ্যানেলটি 3 বা 4 হয় তবে আপনাকে অ্যারে সূচিটি পছন্দ করতে হবে

x*image.height*number_channel + y*number_channel + channel

0

স্ট্যাশঅফকোডের উত্তরে মাত্র দুটি নোট:

  1. এটি কেবল গ্রেস্কেল, অস্বচ্ছ ক্যানভাসের জন্য কাজ করে (সাদা দিয়ে ভরাটরেট তারপর কালো দিয়ে আঁকুন, বা বিপরীতমুখী)
  2. লাইনগুলি পাতলা হয়ে গেলে এটি ব্যর্থ হতে পারে (p 1px লাইন প্রস্থ)

পরিবর্তে এটি করা ভাল:

স্ট্রোক করুন এবং পূরণ করুন #FFFFFF, তারপরে এটি করুন:

imageData.data[i] = (imageData.data[i] >> 7) * 0xFF

এটি এটি 1px প্রস্থ সহ লাইনের জন্য সমাধান করে।

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


0

এখানে জাভাস্ক্রিপ্টে ব্রেসেনহ্যামের অ্যালগরিদমের একটি প্রাথমিক বাস্তবায়ন। এটি এই উইকিপিডিয়া নিবন্ধে বর্ণিত পূর্ণসংখ্যা-গাণিতিক সংস্করণের উপর ভিত্তি করে: https://en.wikedia.org/wiki/Bresenham%27s_line_algorithm

    function range(f=0, l) {
        var list = [];
        const lower = Math.min(f, l);
        const higher = Math.max(f, l);
        for (var i = lower; i <= higher; i++) {
            list.push(i);
        }
        return list;
    }

    //Don't ask me.
    //https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
    function bresenhamLinePoints(start, end) {

        let points = [];

        if(start.x === end.x) {
            return range(f=start.y, l=end.y)
                        .map(yIdx => {
                            return {x: start.x, y: yIdx};
                        });
        } else if (start.y === end.y) {
            return range(f=start.x, l=end.x)
                        .map(xIdx => {
                            return {x: xIdx, y: start.y};
                        });
        }

        let dx = Math.abs(end.x - start.x);
        let sx = start.x < end.x ? 1 : -1;
        let dy = -1*Math.abs(end.y - start.y);
        let sy = start.y < end.y ? 1 : - 1;
        let err = dx + dy;

        let currX = start.x;
        let currY = start.y;

        while(true) {
            points.push({x: currX, y: currY});
            if(currX === end.x && currY === end.y) break;
            let e2 = 2*err;
            if (e2 >= dy) {
                err += dy;
                currX += sx;
            }
            if(e2 <= dx) {
                err += dx;
                currY += sy;
            }
        }

        return points;

    }

0

এরকম কিছু চেষ্টা করুন canvas { image-rendering: pixelated; }

আপনি যদি কেবল একটি লাইন অ্যান্টিএলাইজড না করে তৈরি করার চেষ্টা করছেন তবে এটি কাজ করবে না।

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

ctx.fillRect(4, 4, 2, 2);
canvas {
  image-rendering: pixelated;
  width: 100px;
  height: 100px; /* Scale 10x */
}
<html>
  <head></head>
  <body>
    <canvas width="10" height="10">Canvas unsupported</canvas>
  </body>
</html>

যদিও আমি অনেক ব্রাউজারে এটি পরীক্ষা করিনি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.