जब एक <कैनवास> स्केलिंग इंटरपोलेशन को अक्षम करें


126

नोट : इसका मतलब यह है कि जब मौजूदा कैनवास तत्व को स्केल किया जाता है ,तो कैनवास की सतह पर लाइनों या ग्राफिक्स को कैसे प्रस्तुत किया जाता है ,इसके साथ नहीं । दूसरे शब्दों में, इसमें स्केल किए गए तत्वों के प्रक्षेप केसाथ सब कुछ है, औरएक कैनवास पर ग्राफिक्स के एंटीएलियासिंग केसाथ कुछ नहीं करना है। मैं इस बात से चिंतित नहीं हूँ कि ब्राउज़र कैसे रेखाएँ खींचता है; मुझे इस बात की परवाह है कि जब ब्राउज़रको स्केल किया जाता है तोब्राउज़र अपने आप को कैसे प्रस्तुत करताहै।


क्या कोई कैनवास संपत्ति या ब्राउज़र सेटिंग है जो मैं स्केलिंग <canvas>तत्वों को प्रक्षेपित करने के लिए प्रोग्रामेटिक रूप से बदल सकता हूं ? एक क्रॉस-ब्राउज़र समाधान आदर्श है लेकिन आवश्यक नहीं है; वेबकिट-आधारित ब्राउज़र मेरा मुख्य लक्ष्य हैं। प्रदर्शन बहुत महत्वपूर्ण है।

यह सवाल सबसे समान है लेकिन समस्या को पर्याप्त रूप से नहीं बताता है। इसके लायक क्या है, मैंने कोशिश की हैimage-rendering: -webkit-optimize-contrast कोई फायदा नहीं उठाया।

आवेदन HTML5 + JS में लिखा गया "रेट्रो" 8-बिट स्टाइल वाला गेम होगा, यह स्पष्ट करने के लिए कि मुझे क्या चाहिए।


उदाहरण के लिए, यहाँ एक उदाहरण है। ( लाइव संस्करण )

मान लीजिए मेरे पास एक 21x21 कैनवास है ...

<canvas id='b' width='21' height='21'></canvas>

... जो सीएसएस है जो तत्व को 5 गुना बड़ा (105x105) बनाता है:

canvas { border: 5px solid #ddd; }
canvas#b { width: 105px; height: 105px; } /* 5 * 21 = 105 */

मैं कैनवास पर एक सरल 'X' आकर्षित करता हूं जैसे:

$('canvas').each(function () {
    var ctx = this.getContext("2d");
    ctx.moveTo(0,0);
    ctx.lineTo(21,21);
    ctx.moveTo(0,21);
    ctx.lineTo(21,0);
    ctx.stroke();
});

बाईं ओर की छवि क्रोमियम (14.0) प्रस्तुत करती है। दाईं ओर की छवि वह है जो मैं चाहता हूं (उदाहरण के लिए हाथ खींचा गया)।

क्रोम स्केल किए गए कैनवास तत्वों को प्रक्षेपित करता है एक गैर-प्रक्षेपित संस्करण


1
कुछ हद तक संबंधित है, हालांकि समान नहीं है: stackoverflow.com/questions/195262/…
HostileFork का कहना है कि SE पर भरोसा न करें

1
मेरा मानना ​​है कि सवाल लाइन-ड्राइंग फ़ंक्शन का उल्लेख है जो एंटी-अलियास लाइनों को ड्राइंग करता है। मैं यह जिक्र कर रहा हूं कि कैसे कैनवास आकार के तत्वों को डिफ़ॉल्ट रूप से प्रक्षेप के साथ प्रदान किया जाता है।
namuol

हाँ, क्षमा करें ... मैंने पहले वही प्रश्न सोचा था फिर तुरंत मेरी गलती पर ध्यान दिया। : - / क्या हुआ अगर आप jsmanipulate के पिक्सेलेशन फ़िल्टर का उपयोग करने की कोशिश कर रहे थे? joelb.me/jsmanipulate
HostileFork का कहना है कि SE सेप

1
यह तस्वीरों के लिए एक छवि-फ़िल्टर का अधिक हिस्सा है।
namuol

हाँ, लेकिन अगर यह आपकी बाईं छवि को आपकी दाहिनी छवि के एक अच्छे संस्करण में बदल कर आपको खुश करता है तो यह एक क्रॉस-ब्राउज़र समाधान प्रदान कर सकता है (यह देखते हुए कि यह ड्राइंग मोड, सार्वभौमिक या अन्यथा के लिए झंडा खोजने के लिए बहुत आशाजनक नहीं है। , WebKit में)। क्या यह एक व्यवहार्य विकल्प है जो उस समस्या पर निर्भर करता है जिसे आप हल करने की कोशिश कर रहे हैं ... अगर आपको वास्तव में असतत पिक्सेल ड्राइंग की आवश्यकता है या यदि आप यह सुनिश्चित करने की कोशिश कर रहे हैं कि परिणाम एक निश्चित ग्रैन्युलैरिटी के साथ पिक्सेलित है।
HostileFork का कहना है कि

जवाबों:


126

अंतिम अपडेट: 2014-09-12

क्या एक कैनवास संपत्ति या ब्राउज़र सेटिंग है जो मैं स्केलिंग तत्वों को इंटरपोलेशन को अक्षम करने के लिए प्रोग्रामेटिक रूप से बदल सकता हूं?

इसका जवाब शायद किसी दिन है । अभी के लिए, आपको वह प्राप्त करने के लिए हैक-अराउंड का सहारा लेना होगा।


image-rendering

CSS3 के काम का मसौदा एक नई संपत्ति की रूपरेखा तैयार करता है,image-rendering जो मुझे चाहिए वह करना चाहिए:

छवि प्रदान करने वाली संपत्ति उपयोगकर्ता-एजेंट को एक संकेत प्रदान करती है कि छवि को छोटा करने के लिए किन पहलुओं को संरक्षित करना सबसे महत्वपूर्ण है, एक उपयुक्त स्केलिंग एल्गोरिदम की पसंद में उपयोगकर्ता-एजेंट की सहायता करना।

विनिर्देश तीन स्वीकृत मूल्यों की रूपरेखा: auto, crisp-edges, और pixelated

pixelated:

छवि को स्केल करते समय, "निकटतम पड़ोसी" या इसी तरह के एल्गोरिथ्म का उपयोग किया जाना चाहिए, ताकि छवि बस बहुत बड़े पिक्सेल से बना प्रतीत हो। स्केलिंग करते समय, यह ऑटो के समान है।

स्टैंडर्ड? क्रॉस ब्राउज़र?

चूंकि यह केवल एक काम का मसौदा है , इस बात की कोई गारंटी नहीं है कि यह मानक बन जाएगा। ब्राउज़र समर्थन वर्तमान में सबसे अच्छा है।

मोज़िला डेवलपर नेटवर्क के पास कला की वर्तमान स्थिति के लिए समर्पित एक पूरी तरह से पेज है जिसे मैं पढ़ने की सलाह देता हूं।

वेबकिट डेवलपर्स ने शुरू में इसे अस्थायी रूप से लागू-webkit-optimize-contrast करने के लिए चुना था , लेकिन क्रोमियम / क्रोम वेबकिट के एक संस्करण का उपयोग नहीं करते हैं जो इसे लागू करता है।

अपडेट: 2014-09-12

क्रोम 38 अब समर्थन करता है image-rendering: pixelated !

फ़ायरफ़ॉक्स एक बग रिपोर्टimage-rendering: pixelated लागू करने के लिए खुला है , लेकिन-moz-crisp-edges अभी के लिए काम करता है।

उपाय?

अब तक का सबसे क्रॉस-प्लेटफॉर्म, सीएसएस-केवल समाधान इस प्रकार है:

canvas {
  image-rendering: optimizeSpeed;             /* Older versions of FF          */
  image-rendering: -moz-crisp-edges;          /* FF 6.0+                       */
  image-rendering: -webkit-optimize-contrast; /* Safari                        */
  image-rendering: -o-crisp-edges;            /* OS X & Windows Opera (12.02+) */
  image-rendering: pixelated;                 /* Awesome future-browsers       */
  -ms-interpolation-mode: nearest-neighbor;   /* IE                            */
}

अफसोस की बात है कि यह अभी तक सभी प्रमुख HTML5 प्लेटफार्मों पर काम नहीं करेगा (क्रोम, विशेष रूप से)।

बेशक, कोई भी मैन्युअल रूप से जावास्क्रिप्ट में उच्च-रिज़ॉल्यूशन कैनवास सतहों पर निकटतम-पड़ोसी प्रक्षेप का उपयोग करके छवियों को स्केल कर सकता है, या यहां तक ​​कि पूर्व-स्केल छवियां सर्वर-साइड भी हो सकती हैं, लेकिन मेरे मामले में यह महंगा होगा, इसलिए यह एक व्यवहार्य विकल्प नहीं है।

इस सभी FUD को पाने के लिए ImpactJS एक टेक्सचर प्री-स्केलिंग तकनीक का इस्तेमाल करता है। इम्पैक्ट के डेवलपर, डोमिनिक ज़ैब्लेव्स्की ने इस बारे में एक बहुत ही गहन लेख लिखा था (उन्होंने अपने शोध में इस सवाल का हवाला देते हुए यह भी कहा)।

एक कैनवास-आधारित समाधान के लिए साइमन का जवाब देखें जो imageSmoothingEnabledसंपत्ति पर निर्भर करता है (पुराने ब्राउज़रों में उपलब्ध नहीं है, लेकिन पूर्व-स्केलिंग और बहुत व्यापक रूप से समर्थित की तुलना में सरल है)।

लाइव डेमो

यदि आप canvasतत्वों पर एमडीएन लेख में चर्चा की गई सीएसएस संपत्तियों का परीक्षण करना चाहते हैं, तो मैंने इस फिडेल को बनाया है जो आपके ब्राउज़र के आधार पर कुछ इस तरह प्रदर्शित होना चाहिए, धुंधला या नहीं। एक 4: 1 (64x64 से 256x256) एक आइसोमेट्रिक पिक्सेल-कला शैली टीवी की छवि


छवि-प्रतिपादन कहीं और काम करता है, लेकिन वेबकिट ब्राउज़र। मैं वास्तव में आशा करता हूं कि क्रोम / क्रोमियम / सफारी स्टाफ अच्छी तरह से पढ़ता है कि "लो-लोड स्थितियों में ईपीएक्स इंटरपोलेशन पर स्विच करें" का क्या मतलब है। जब मैंने पहली बार वाक्य पढ़ा तो मुझे लगा कि ऑप्टिमाइज़-कॉन्ट्रास्ट नए रंगों को कम लोड में बनाने की अनुमति देता है, लेकिन NO: en.wikipedia.org/wiki/…
Timo Kähkönen

2
Mac और Windows पर ओपेरा 12.02 इमेज-रेंडरिंग का समर्थन करता है: -o-crisp- edge ( jsfiddle.net/VAXrL/21 ), ताकि आप इसे अपने उत्तर में जोड़ सकें।
तिमो क्वाकोनेन

जब मैं ब्राउज़र ज़ूम बढ़ा रहा हूं तो क्या यह काम करना चाहिए? मैंने विंडोज 7 पर FF 22, क्रोम 27 और IE 10 के साथ ड्राइंग का परीक्षण किया है जब ब्राउज़र ज़ूम 150% है और परिणाम सभी ब्राउज़रों पर धुंधला है। जब मैं कैनवास की चौड़ाई और ऊंचाई को दोगुना करता हूं और इसे सीएसएस के साथ मूल चौड़ाई और ऊंचाई पर वापस सेट करता हूं तो यह तेज रेखाएं खींचता है।
पाब्लो

यह एक अच्छा सवाल है। अगर उपयोगकर्ता-निर्दिष्ट स्केलिंग व्यवहार के लिए कोई युक्ति है तो मुझे यकीन नहीं है।
नामुएल

1
मैं Chrome पर 78 (वर्तमान भविष्य से!) हूं। मैं "इमेज-रेंडरिंग: पिक्सेलेटेड" देख रहा हूं। काम कर रहे। ऐसा लगता है कि इसे 2015 में क्रोम 41 में जोड़ा गया था: Developers.google.com/web/updates/2015/01/pixelated
MrColes

61

नया उत्तर 7/31/2012

यह अंत में कैनवास की कल्पना में है!

विनिर्देश ने हाल ही में एक संपत्ति को जोड़ा है imageSmoothingEnabled, जिसे कहा जाता है , जो trueनिर्धारित करता है कि गैर-पूर्णांक निर्देशांक या आरेखित स्केल पर खींची गई छवियाँ एक चिकनी एल्गोरिथ्म का उपयोग करेंगी या नहीं। यदि यह falseतब सेट होता है तो निकटतम-पड़ोसी का उपयोग किया जाता है, तो एक कम चिकनी छवि का निर्माण होता है और इसके बजाय सिर्फ बड़े आकार के पिक्सेल बनाते हैं।

छवि चौरसाई हाल ही में कैनवास विनिर्देश में जोड़ी गई है और सभी ब्राउज़रों द्वारा समर्थित नहीं है, लेकिन कुछ ब्राउज़रों ने इस संपत्ति के विक्रेता-उपसर्ग संस्करणों को लागू किया है। संदर्भ mozImageSmoothingEnabledमें फ़ायरफ़ॉक्स और webkitImageSmoothingEnabledक्रोम और सफारी में मौजूद है , और इन्हें गलत पर सेट करने से एंटी-एलियासिंग होने से बंद हो जाएगा। दुर्भाग्य से, लेखन के समय, IE9 और ओपेरा ने इस संपत्ति, विक्रेता को उपसर्ग या अन्यथा लागू नहीं किया है।


पूर्वावलोकन: JSFiddle

परिणाम:

यहाँ छवि विवरण दर्ज करें


1
दुर्भाग्य से ऐसा लगता है कि यह अभी भी काम नहीं करता है। शायद मुझे कुछ याद आ रहा है? यहाँ एक परीक्षण है: jsfiddle.net/VAXrL/187
namuol

12
आपको काम करने के लिए कैनवास एपीआई का उपयोग करना होगा, आप कभी भी सीएसएस के साथ स्केल नहीं कर सकते हैं और कैनवास एपीआई इसे प्रभावित करते हैं! तो कुछ इस तरह से: jsfiddle.net/VAXrL/190
साइमन सरिस

1
लेकिन इस समस्या की प्रकृति वास्तव में कैनवास के बारे में नहीं है। यह इस बारे में है कि ब्राउज़र <कैनवास> तत्वों सहित स्केल की गई छवियों को कैसे प्रस्तुत करता है।
namuol

4
यदि आप CSS का उपयोग करते हैं, तो namuol का समाधान काम करेगा। यदि आप कैनवस पर मैन्युअल रूप से छवि को स्केल करते हैं, तो साइमन का समाधान काम करता है। यह साफ है कि दोनों मामलों के समाधान हैं, इसलिए आप दोनों को धन्यवाद!
शॉन लेब्रोन

IE 11 के लिए: msImageSmoothingEnabled मेरे लिए काम करता है! msdn.microsoft.com/en-us/library/dn265062(v=vs.85).aspx
स्टीव

11

संपादित करें 7/31/2012 - यह कार्यक्षमता अब कैनवास कल्पना में है! यहां देखें अलग जवाब:

https://stackoverflow.com/a/11751817/154112

पुराना उत्तर पोस्टीरिटी के लिए नीचे है।


आपके इच्छित प्रभाव के आधार पर, आपके पास इसका एक विकल्प है:

var can = document.getElementById('b');
var ctx = can.getContext('2d');
ctx.scale(5,5);
$('canvas').each(function () {
    var ctx = this.getContext("2d");
    ctx.moveTo(0,0);
    ctx.lineTo(21,21);
    ctx.moveTo(0,21);
    ctx.lineTo(21,0);
    ctx.stroke();
});

http://jsfiddle.net/wa95p/

जो इसे बनाता है:

यहाँ छवि विवरण दर्ज करें

शायद नहीं जो आप चाहते हैं। लेकिन अगर आप केवल शून्य कलंक लग रहे थे तो वह टिकट होगा इसलिए मैं इसे केवल मामले में पेश करूंगा।

एक अधिक कठिन विकल्प पिक्सेल हेरफेर का उपयोग करना और नौकरी के लिए खुद को एक एल्गोरिथ्म लिखना है। पहली छवि का प्रत्येक पिक्सेल नई छवि पर पिक्सेल का 5x5 ब्लॉक बन जाता है। यह imagedata के साथ करने के लिए बहुत मुश्किल नहीं होगा।

लेकिन कैनवस और सीएसएस अकेले ही आपकी इच्छा के अनुसार एक-दूसरे को स्केल करने के लिए आपकी मदद नहीं करेंगे।


हाँ, यही मैं डरता था। जाहिर है, image-rendering: -webkit-optimize-contrastचाल करना चाहिए , लेकिन कुछ भी करने के लिए प्रतीत नहीं होता है। मैं निकटतम-पड़ोसी प्रक्षेप का उपयोग करके एक कैनवास की सामग्री को स्केल करने के लिए एक फ़ंक्शन को रोल करने में देख सकता हूं।
21

मैंने मूल रूप से आपके उत्तर को स्वीकार कर लिया है; मैंने इसे अभी के लिए रद्द कर दिया है क्योंकि इस बारे में भ्रम की स्थिति है कि यह डुप्लिकेट है या नहीं।
नमस्ते 13

मेरे पास कुछ शोध करने के बाद अधिक पूर्ण उत्तर है और अपना उत्तर प्रदान करने के लिए प्रश्न को फिर से खोलना चाहूंगा।
namuol

3

Google क्रोम में, कैनवास छवि पैटर्न प्रक्षेपित नहीं होते हैं।

यहाँ एक कार्यकारी उदाहरण namuol उत्तर http://jsfiddle.net/pGs4f/ से संपादित किया गया है

ctx.scale(4, 4);
ctx.fillStyle = ctx.createPattern(image, 'repeat');
ctx.fillRect(0, 0, 64, 64);

यह अब तक का सबसे आकर्षक वर्कअराउंड है। अभी तक प्रदर्शन के बारे में निश्चित नहीं है, लेकिन यह पूरी तरह से देखने लायक है। मैं इसे आज़माऊँगा।
नामुएल

नो-रिपीट के बजाय रिपीट का उपयोग तेज है। पता नहीं क्यों। यह भी बहुत तेज़ है, तीन। CansRenderer में इसका इस्तेमाल करते हैं
saviski

6
अद्यतन: अब और नहीं (रेटिना प्रदर्शन समर्थन जोड़ा के कारण?) क्रोम 21 के साथ काम करता नए संस्करण jsfiddle.net/saviski/pGs4f/12 imageSmoothingEnabled का उपयोग कर साइमन द्वारा बताया
saviski

जब रेटिना रिज़ॉल्यूशन सामान्य आता है, तो चीजें बहुत बदल जाती हैं। जब iPhone4-5 शैली 326dpi (128dpcm) रेटिना डिस्प्ले 24 इंच (52x32cm) मॉनिटर पर आती है, तो स्क्रीन का आकार 6656 x 4096 px होगा। फिर एंटीएलियासिंग खराब है, और सभी ब्राउज़र विक्रेताओं (यहां तक ​​कि वेबकिट आधारित) को एंटीएलियासिंग को अक्षम करने की अनुमति देने के लिए मजबूर किया जाता है। Antialiasing cpu- सघन ऑपरेशन है और 6656 x 4096 px छवि का antialiasing बहुत धीमा होगा, लेकिन इस तरह के प्रदर्शन में सौभाग्य से अनावश्यक है।
तिमो Kähkönen

1
बस एक साइड-नोट के रूप में, यहाँ एक अच्छा बेंचमार्क अबॉर्शन
yckart

1

Saviski के वैकल्पिक हल explicated यहाँ का वादा किया जाता है, क्योंकि इस पर काम करता है:

  • क्रोम 22.0.1229.79 मैक ओएस एक्स 10.6.8
  • क्रोम 22.0.1229.79 मीटर विंडोज 7
  • क्रोमियम 18.0.1025.168 (डेवलपर बिल्ड 134367 लिनक्स) उबंटू 11.10
  • फ़ायरफ़ॉक्स 3.6.25 विंडोज 7

लेकिन निम्नलिखित में काम नहीं करता है, लेकिन सीएसएस छवि-प्रतिपादन का उपयोग करके समान प्रभाव प्राप्त किया जा सकता है:

  • फ़ायरफ़ॉक्स 15.0.1 मैक ओएस एक्स 10.6.8 (छवि-प्रतिपादन: -मोज़-क्रिस्प-किनारों में काम करता है इस )
  • ओपेरा 12.02 मैक ओएस एक्स 10.6.8 (छवि-प्रतिपादन: -o-कुरकुरा-किनारों में काम करता है इस )
  • ओपेरा 12.02 विंडोज 7 (छवि प्रतिपादन: में -ओ-कुरकुरा-किनारों काम करता है इस )

समस्याग्रस्त ये हैं, क्योंकि ctx.XXXImageSmoothingEnabled काम नहीं कर रहा है और छवि-प्रतिपादन काम नहीं कर रहा है:

  • सफारी 5.1.7 मैक ओएस एक्स 10.6.8। (छवि-प्रतिपादन: -webkit- ऑप्टिमाइज़-कंट्रास्ट काम नहीं करता है)
  • सफ़ारी 5.1.7 विंडोज 7 (इमेज-रेंडरिंग: -webkit- ऑप्टिमाइज़-कंट्रास्ट काम नहीं करता है)
  • IE 9 विंडोज 7 (सेमी-इंटरपोलेशन-मोड: निकटतम पड़ोसी काम नहीं करता है)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.