Как да определите дали изображението използва прозрачност в Javascript?

Бих искал да мога да открия дали изображение тип лого има прозрачен фон или не, нека си представим, че две подобни изображения са .png файлове, но едното има бял фон, а другото има прозрачен фон, как бих могъл да определи този с прозрачност?

Опитах да използвам colorthief, но той не отчита прозрачността, така че реших да го направя сам на canvas. Първото решение би било да преобразувате файла png в jpg и ако цветът на фона на jpg след преобразуването изглежда черен, това е прозрачно лого, но това може да е проблем за потребители с черен фон и бели лога. Има ли по-добро решение от това?

http://jsfiddle.net/9s5qf5cu/

от png към jpg :

var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);

var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');


function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
        var img = new Image();
        img.onload = function(){
            canvas.width = 100;
            canvas.height = 100;
            ctx.drawImage(img,0,0, 100, 100);
            document.getElementById("image").src = canvas.toDataURL("image/jpeg");
        }
        img.src = event.target.result;

    }
    reader.readAsDataURL(e.target.files[0]);     
}

person Hiroyuki Nuri    schedule 15.07.2017    source източник
comment
Първото решение би било да конвертирате png файла в jpg ‹-- За ваша информация: JPEG няма алфа канал.   -  person Zomry    schedule 15.07.2017
comment
@Zomry Знам това, но когато конвертирате png файл в jpg, получавате черен фон, ако изображението е прозрачно.   -  person Hiroyuki Nuri    schedule 15.07.2017
comment
Вероятно има много начини за това, единият би бил да направите това, което предлагате, може би като проверите всички пиксели и определите дали определен брой пиксели имат същия цвят като фона. Използването на друго изображение като фон би направило много малко вероятно голям брой пиксели да са еднакви и т.н. Правилното нещо, което трябва да направите, е да изпратите изображението на сървъра и да използвате ImageMagick, за да проверите алфа канала.   -  person adeneo    schedule 15.07.2017
comment
@Lindow Вие не получавате черен фон, когато го конвертирате. Софтуерът или алгоритъмът, който ще използвате, е този, който решава да зададе черен фон. Но може да е розово!   -  person lilezek    schedule 15.07.2017
comment
@lilezek Да, разбирам това, но казвам, че в моя случай на jsfiddle е черно и мога да го използвам, за да открия дали фонът е прозрачен   -  person Hiroyuki Nuri    schedule 15.07.2017
comment
но когато конвертирате png файл в jpg, получавате черен фон, ако изображението е прозрачно - и как това ще ви помогне да определите дали имате PNG с прозрачен фон или такъв, който е черен в началото с? Копирането на PNG върху платното и преминаването с getImageData и проверката на нивото на алфа на всеки отделен пиксел предполагам, че би било начин (ако приемем, че копирането на изображение, което съдържа такива прозрачни части върху празно платно, запазва тези стойности непокътнати.)   -  person CBroe    schedule 15.07.2017
comment
@CBroe Интересно, не знаех, че можете да проверите алфа нивото на всеки пиксел върху платно.   -  person Hiroyuki Nuri    schedule 15.07.2017
comment
getImageData връща ImageData обект, който има свойство data, съдържащо едномерен масив от цели числа, R , G, B и A стойност за всеки пиксел, само един след друг.   -  person CBroe    schedule 15.07.2017
comment
но казвам, че в моя случай на jsfiddle е черен - добре, това е вероятно, защото програмата, която е създала вашия PNG, просто е поставила там черни пиксели с алфа стойност нула ... но това може да бъде и всеки друг цвят, например ако потребителят на графична програма е избрал област чрез инструмент за магическа пръчица по цвят и след това е направил своя избор прозрачен.   -  person CBroe    schedule 15.07.2017
comment
Предполагам, че това е малко проблематично, всяко изображение, вмъкнато в платно, което не е от същия произход, ще бъде опетнено, така че всяко изображение, използвано в JSFiddle, трябва да идва от този произход   -  person adeneo    schedule 15.07.2017
comment
Има демонстрация на MDN , малко надолу по страницата   -  person adeneo    schedule 15.07.2017
comment
Трябва да е достатъчно просто за постигане, ако приемем, че вече имате кода за зареждане на PNG върху платно (създаване на платно с правилните размери) ... Получавате данните за изображението и след това можете да проверите в обикновен for цикъл, започващ от 0 , увеличавайки брояча на цикъла с 4 всеки път, независимо дали алфа стойността показва липса на прозрачност за този пиксел. Ако срещнете такъв, поставете флаг и излезте от цикъла ...   -  person CBroe    schedule 15.07.2017


Отговори (1)


Използвайте тази функция, като предадете вашия контекст и вашето платно. След това ще премине през алфа канала, докато намери запис, който не е напълно непрозрачен.

function hasAlpha (context, canvas) {
    var data = context.getImageData(0, 0, canvas.width, canvas.height).data,
        hasAlphaPixels = false;
    for (var i = 3, n = data.length; i < n; i+=4) {
        if (data[i] < 255) {
            hasAlphaPixels = true;
            break;
        }
   }
   return hasAlphaPixels;
}

Забележка: това няма да работи, ако платното ви е опетнено.

person Zomry    schedule 15.07.2017
comment
Благодаря, имам проблем с работата: jsfiddle.net/9s5qf5cu/2 какво да въведа в контекста? - person Hiroyuki Nuri; 15.07.2017
comment
В тази функция това би било ctx. - person Zomry; 15.07.2017
comment
Всяко изображение, което опитвам, изглежда прозрачно, дори и да не е - person adeneo; 15.07.2017
comment
Разбирам, започнах с i от 0, докато трябваше да започне от 3. Опитайте тази версия: jsfiddle.net /Zomry/g0mt5obw - person Zomry; 15.07.2017