Изобразяване на най-близкия съсед в Canvas

Имам спрайт, който анимира с помощта на лист със спрайтове. Той е само 16x16, но искам да го мащабирам до около 64x64 в цялата му доброта на пикселите!

алтернативен текст

Резултатите са ужасни, разбира се браузърът го анти-алиасинг. :/

Благодаря!

РЕДАКТИРАНЕ: Не е необходим css, ето моята функция за рисуване.

function drawSprite(offsetx:number,offsety:number,posx:number,posy:number){
    ctx.drawImage(img, offsetx*32, offsety*32, 32, 16, posx*32, posy*8, 128, 32);
}

Вижте, че някак работи тук (codepen)


person DevEarley    schedule 21.07.2010    source източник
comment
Вижте също моя отговор на този въпрос което показва как да използвате JavaScript + Canvas, за да използвате най-близкия съсед във всеки браузър.   -  person Phrogz    schedule 17.01.2012
comment
Отговорът, свързан в горния коментар, е много по-пълен   -  person sfridman    schedule 04.06.2015


Отговори (2)


В случай, че някой някога се натъкне на това отново (като мен), Webkit поддържа -webkit-optimize-contrast стойност за image-rendering, което (в момента) е реализация на мащабирането на най-близкия съсед. Може да се прилага както върху изображения, така и върху платна.

Ето един пример как става.

.nn128 {
    width: 128px;
    height: 128px;
    image-rendering: -moz-crisp-edges;
    image-rendering: -webkit-optimize-contrast;
}

<canvas class="nn128" width="16" height="16"></canvas>
<img src="path/to/small/image.png" alt="Small image" class="nn128">

С тази настройка както WebkitSafari, така и Gecko/Firefox ще увеличат пространството на платното 16x16 и малкото изображение до 128x128 с алгоритъма за най-близък съсед.

АКТУАЛИЗАЦИЯ Отговорът първоначално посочва, че браузърите Webkit поддържат това; всъщност от 2011-12-24 той работи със Safari на Mac OS и Chrome на Mac OS, но не и с Chrome one Windows (Safari на Windows не е проверен), както е посочено на Проблем 106662 на програмата за проследяване на грешки в Chromium. Лексически, Chrome под Windows ще приеме стойността -webkit-optimize-contrast в CSS style sheet, но това няма да има никакъв ефект. Очаквам, че ще проработи някой ден и този метод ще бъде правилният начин за увеличаване на най-близкия съсед, но засега използването на този метод означава, че потребителите на Windows Chrome ще трябва да живеят с размазването.

person zneak    schedule 24.08.2011
comment
Има ли някакъв начин да предоставите проба? Знам, че е доста ясно... но все пак наистина бих го оценил. - person DevEarley; 26.08.2011
comment
Това изглежда не работи от 30 септември 2011 г. Използвам Chrome 14.0 и -webkit-optimize-contrast очевидно не прави нищо, за да промени начина, по който се интерполират изображенията. Той приема стойността за image-rendering, така че трябва да има известно ниво на поддръжка; може би е счупено? - person namuol; 01.10.2011
comment
@namuol, съществува в последните ревизии на WebKit; Трябва да призная, че не си спомням да съм проверявал. Работи поне със Safari 5 и съм малко изненадан, че все още не е стигнал до Chrome. - person zneak; 01.10.2011
comment
Все още не е в Chrome бета. WebKit Inspector не се оплаква от това, така че изглежда, че знае стойността на свойството -webkit-optimize-contrast, но няма никакъв ефект. Въпреки това работи добре в WebKit nightlies. - person Tower; 24.12.2011
comment
@rFactor, има доклад за грешка в chromium за това – ще го добавя към отговора, тъй като това е доста дългогодишен проблем. - person zneak; 25.12.2011
comment
От днес това работи в Chrome v17 на OS X, но не на Safari v5.1.2 на OS X. - person Phrogz; 17.01.2012

Във Firefox можете да използвате това:

canvas {
  image-rendering: -moz-crisp-edges;
}

Но доколкото знам за всеки друг браузър нямате късмет. Един от начините за заобикаляне на това може би е да увеличите своя спрайт до 64x64 във Photoshop (или каквото и да е), след което да го използвате намален в canvas. По този начин поне изображението няма да се замъгли при „увеличаване“. Все пак няма да ви даде чистия режим7 като добротата на най-близкия съсед.

Можете да напишете свой собствен код за мащабиране, като използвате обекта imageData. По този начин ще понесете значителна загуба на производителност, но за изображение 16x16 може да не е толкова значителна.

person MooGoo    schedule 22.07.2010
comment
Иска ми се Opera или Safari да имат опция за изобразяване на изображения за най-близкия съсед. :/ Благодаря! - person DevEarley; 22.07.2010
comment
Това вече не изглежда да работи във firefox; вижте тази цигулка в последната версия като тест: jsfiddle.net/gingerbeardman/XQkXy - person namuol; 01.10.2011