Scrape obrazów z canvas ze strony internetowej

Scrape obrazów z canvas ze strony internetowej
CA
  • Rejestracja:ponad 6 lat
  • Ostatnio:8 miesięcy
  • Postów:60
0

Witajcie, pytanie dotyczy możliwości pobierania obrazów generowanych przez canvas. Chciałbym pobierać sobie obrazki ze strony: https://zehfernandes.com/generativeplanets/builder (przez Greasemonkey-a) - na użytek prywatny.

Przerobiłem do tej pory toDataURL, ale w przypadku grafik z powyższej strony ta metoda nie zadziała - zwraca pusty obraz. Czy istnieje jakaś możliwość pobrania snapshota takiej animowanej grafiki przy pomocy JS?

edytowany 1x, ostatnio: Riddle
RG
coś jest dla: js screenshoot
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:minuta
  • Lokalizacja:Laska, z Polski
  • Postów:10081
0

Próbowałeś wpisać w google "greasemonkey scrape canvas"?

CA
  • Rejestracja:ponad 6 lat
  • Ostatnio:8 miesięcy
  • Postów:60
0
Riddle napisał(a):

Próbowałeś wpisać w google "greasemonkey scrape canvas"?

Tak, siedzę nad tym od 2-ch dni i sprawdzałem różne sposoby. W przypadku statycznych canvasów nie ma problemu, jedynie z tym animowanym coś nie działa. Sprawdzałem też kilka wtyczek do przeglądarek, ale w takim przypadku grafika albo jest pusta, albo np. ucięta w połowie

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:minuta
  • Lokalizacja:Laska, z Polski
  • Postów:10081
0
catshy napisał(a):
Riddle napisał(a):

Próbowałeś wpisać w google "greasemonkey scrape canvas"?

Tak, siedzę nad tym od 2-ch dni i sprawdzałem różne sposoby. W przypadku statycznych canvasów nie ma problemu, jedynie z tym animowanym coś nie działa. Sprawdzałem też kilka wtyczek do przeglądarek, ale w takim przypadku grafika albo jest pusta, albo np. ucięta w połowie

A po co dokładnie próbujesz zapisać te animowane canvas?

CA
  • Rejestracja:ponad 6 lat
  • Ostatnio:8 miesięcy
  • Postów:60
0

@Riddle mi właściwie zależy na statycznym obrazie, one są anonimowane na tej stronie. Moje dzieciaki lubią temat kosmosu, planet itd. i chcę im z tych planet porobić różne zabawki w JS, typu minigierki jak memory z odkrywaniem kart, jakieś tam puzzle i inne tego typu. Chciałbym żeby była duża unikatowość tych obrazów i przydałoby mi się tak z kilkaset, a ręczne screenowanie i wycinanie tła to byłaby trochę robota głupiego

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:minuta
  • Lokalizacja:Laska, z Polski
  • Postów:10081
1

To chyba lepiej by było odpalić selenium, wchodzić na tą stronę np 1000 razy, i zapisywać screenshot.

Tu masz kod python który mógłby to zrobić.

Kopiuj
from selenium import webdriver

for i in range(0, 1000):
  driver = webdriver.Chrome(executable_path = 'path\to\chromedriver.exe')
  driver.get("https://zehfernandes.com/generativeplanets/builder")
  driver.save_screenshot('planet.' + str(i) + '.png')

Jakbyś chciał kliknąć na "New random planet", to wywołaj:

Kopiuj
driver.find_element_by_css_selector('span.property-name').click()

Tutaj jest opis jak to zrobić: https://www.browserstack.com/guide/take-screenshot-with-selenium-python

edytowany 5x, ostatnio: Riddle
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:około 3 godziny
  • Postów:8423
0

Spróbuj Puppeteer.

Co do pustego obrazu, może włączyła się polityka bezpieczeństwa
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
Przeczytaj fragment o SecurityError


abc
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 9 godzin
1

Jeśli Twoim celem jest faktycznie zrobić to z kontekstu przeglądarki, to tworząc skrypt do greasemonkey, (czy też tempermonkey) musisz zadbać o kilka rzeczy:

Tak, siedzę nad tym od 2-ch dni i sprawdzałem różne sposoby. W przypadku statycznych canvasów nie ma problemu, jedynie z tym animowanym coś nie działa. Sprawdzałem też kilka wtyczek do przeglądarek, ale w takim przypadku grafika albo jest pusta, albo np. ucięta w połowie

  • przede wszystkim, przed stworzeniem contextu webgl, musisz wymusić by był on stworzony z zachowaniem bufora. Dlatego w cyklu życia strony i też skryptu, musisz jak najwcześniej podmienić metodę getContext np. poprzez nadpisanie prototypu HTMLCanvasElement
    Przykład:

    Kopiuj
    HTMLCanvasElement.prototype.getContext = function(origFn) {
      return function(type, attributes) {
        if (type === 'webgl') {
          attributes = Object.assign({}, attributes, {
            preserveDrawingBuffer: true,
          });
        }
        return origFn.call(this, type, attributes);
      };
    }(HTMLCanvasElement.prototype.getContext);
    

    To powinno zapobiec czyszczeniu bufora w trakcie transformacji do obrazka

  • następnie możesz stworzyć bloba i zemulować ściąganie pliku poprzez atrybut download dostępny na linkach w HTML5, ale to już pewnie wiesz, skoro dostawałeś wcześniej puste obrazki ;)
    PoC:

    Kopiuj
    const data = document.querySelector('#canvas-planet').toDataURL()
    fetch(data).then((b) => b.blob())
    .then(blob => {
        saveFile('planet.png', blob);
    });
    
    function saveFile(fileName,blob){
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.style = "display: none";
        document.body.appendChild(a);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
        a.remove();
    }
    
edytowany 3x, ostatnio: Riddle
TU
Poprawne rozwiązanie i zero plusów, to jest forum programistyczne XD W sumie preserve drawing buffer ten attrybut można ustawić tez poprzez spatchowanie pliku, teraz każda przeglądarka to nawet umożliwia zapisanie zmodyfikowanej strony to łatwo ustawić to na początku przed załadowaniem skryptu lub grasemonkeyem przed załadowaniem strony i innymi skryptami.
P4
  • Rejestracja:ponad rok
  • Ostatnio:ponad rok
  • Postów:4
0

toDataURL czasami wyrzuca pusty obraz, szczegolnie jesli chodzi o grafiki z zabezpieczeniami lub jesli canvas zostal "zanieczyszczony" przez dane z innych zrodel. mozliwe, ze to wlasnie problem tkwi tutaj. ale spoko, sa inne sposoby. 😎 mozna sprobowac toBlob - to tez pozwala na sciaganie obrazkow z canvas, tyle ze nie jest az tak znana. ale jak masz do czynienia z animacja i chcesz snapshot w konkretnym momencie, to znowu, wyzwanie - trzeba trafic w ten wlasciwy frame.co mozesz zrobic, to ustawic w JS interwal, ktory bedzie probowal zlapac klatke w dobrym czasie. 🤔 tylko warto uwazac, zeby nie przesadzic z czestoscia, bo mozna spowolnic dzialanie strony.
jesli chodzi o greasemonkey, to pamietaj, zeby wszystko robic ostroznie. skrypty uzytkownika sa super do personalizowania doswiadczen w necie, ale latwo cos popsuc. 🙈 jak juz bedziesz gotowy poeksperymentowac z JS, warto poczytac o canvas API. znajdziesz tam rozne eventy i metody, ktore moga ci pomoc w twoim projekcie. w koncu czlowiek sie uczy całe zycie.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.