• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Najszybsza metoda na sprawdzenie czy obraz posiada więcej niż jeden kolor

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
297 wizyt
pytanie zadane 25 czerwca 2019 w JavaScript przez BT101 Stary wyjadacz (12,540 p.)

Natknąłem się na ciekawy problem - musiałem sprawdzić czy dany obraz posiada więcej niż 1 kolor. Użyłem funkcji getPixels która zwraca ndarray (wielowymiarowa tablica w js) pikseli. W tej tablicy piksele były ułożone we wzorze [ r, g, b, a, r, g, b, a ... ] czyli każde 4 elementy stanowiły opis jednego piksela. Przekonwertowałem to na zwykłą tablicę tablic we wzorze [ [r, g, b, a], [r, g, b, a] ... ].

Następnie w pętli przeiterowałem po tej tablicy i porównwałem kolejno obecną zagnieżdżoną tablicę z następną zamieniając je na JSON stringa.

Jeżeli którakolwiek z tablic się nie zgadza to ustawiam boolean na false i przerywałem działanie pętli.

const getPixels = require("get-pixels");

//1px only black https://i.imgur.com/dStJ1Og.png
//2px only black https://i.imgur.com/5z46WVp.png
//88x62px only black https://i.imgur.com/ZtGMUh9.png
//88x62px black and red https://i.imgur.com/67IZCaD.png
//220x297px black and red https://i.imgur.com/KTNnJGF.jpg

getPixels("https://i.imgur.com/JiHtQuR.jpg", function(err, ndarray) {
    if(err) {
        console.log("Bad image path!");
        return;
    }

    const uintArr = new Uint8Array(ndarray.data);
    const regularArr = [];
    let oneColor = true;

    for(let i = 0, l = uintArr.length / 4; i < l; i++) {
        regularArr.push([uintArr[4*i], uintArr[4*i+1], uintArr[4*i+2], uintArr[4*i+3]])
    }
    for(let i = 0, l = regularArr.length; i < l; i++) {
        if(regularArr[i + 1]) {
            let currentValString = JSON.stringify(regularArr[i]);
            let nextValString = JSON.stringify(regularArr[i + 1]);

            if(currentValString !== nextValString) {
                oneColor = false;
                break;
            }
        }
    }

    console.log('Is image one color? ', oneColor);
});

Wygląda na to, że kod działa poprawnie. Problemem jest wydajność. Dla obrazu 3000x4000px (12 mln pikseli) operacja trwa 8 sekund (co prawda specjalnie stworzyłem cały czarny obraz z 1 px czerwonym gdzieś w prawym dolnym rogu). To o 90% za dużo. Czy mam jakieś opcje poza zmianą języka?

komentarz 25 czerwca 2019 przez niezalogowany
Jakie formaty plików chcesz obsługiwać?
komentarz 25 czerwca 2019 przez BT101 Stary wyjadacz (12,540 p.)
gif, png

1 odpowiedź

+1 głos
odpowiedź 25 czerwca 2019 przez adrian17 Mentor (350,860 p.)
wybrane 25 czerwca 2019 przez BT101
 
Najlepsza

Coś takiego?

let r = uintArr[0], g = uintArr[1], b = uintArr[2], a = uintArr[3];
for (let i = 0; i < uintArr.length; i += 4) {
	if (
		r != uintArr[i] ||
		g != uintArr[i+1] ||
		b != uintArr[i+2] ||
		a != uintArr[i+3]
	) {
		return false;
	}
}
return true;

 

komentarz 25 czerwca 2019 przez BT101 Stary wyjadacz (12,540 p.)
i porównać Uint32Array z ...?
komentarz 25 czerwca 2019 przez adrian17 Mentor (350,860 p.)
no, porównać jego elementy.
komentarz 25 czerwca 2019 przez BT101 Stary wyjadacz (12,540 p.)
aaa, dobra spróbuje
komentarz 25 czerwca 2019 przez Comandeer Guru (606,240 p.)

żeby nie sprawdzać długości przy każdym "obrocie" pętli

Polecam poczytać: https://mrale.ph/blog/2014/12/24/array-length-caching.html 

komentarz 25 czerwca 2019 przez BT101 Stary wyjadacz (12,540 p.)
a spoko czyli v8 robi to za mnie

Podobne pytania

+3 głosów
2 odpowiedzi 580 wizyt
+2 głosów
1 odpowiedź 4,291 wizyt
0 głosów
1 odpowiedź 812 wizyt

93,174 zapytań

142,185 odpowiedzi

321,970 komentarzy

62,503 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 1157p. - dia-Chann
  2. 1139p. - Łukasz Piwowar
  3. 1131p. - CC PL
  4. 1126p. - Łukasz Eckert
  5. 1118p. - Tomasz Bielak
  6. 1104p. - Michal Drewniak
  7. 1083p. - Marcin Putra
  8. 1078p. - rucin93
  9. 1071p. - rafalszastok
  10. 1054p. - Adrian Wieprzkowicz
  11. 1047p. - Piotr Aleksandrowicz
  12. 1037p. - Michał Telesz
  13. 1023p. - Mariusz Fornal
  14. 1017p. - Mikbac
  15. 1005p. - ssynowiec
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...