Canvas toDataUrl geht irgendwie nicht
Henry
- canvas
- html
Hallo,
habe jetzt Stunden gebraucht um zu sehen was da falsch läuft. Anscheinend ist das wieder mal irgend so ein ein Sicherheitsding. Ich kann mir Bilder anschauen, sie auch einbinden, sogar eine Canvas Kopie machen. Aber dann, sobald ich den, ja sowieso bekannten, Inhalt wieder in ein Bild einfügen möchte. Geht gar nichts. konsole gibt auch nur einen nichtssagenden Sicherheitshinweis heraus. Das dumme daran war, weil wenn einmal geklappt, sozusagen gecached, dann funktionierts, so kam ich nicht auf das Problem.
Was habe ich denn dann für eine Möglichkeit, wenn ich ein Bild wieder aus dem üblichen Canvas zurückkonvertieren möchte, so das es dann entsprechend runtergeladen werden kann.
Hier zum testen.
Gruss
Henry
Schau mal, ob Dir das hier weiter hilft:
https://github.com/iddan/react-native-canvas/blob/master/src/Image.js#L23
Pardon. Das war der falsche Link.
Sollte der hier sein
... der zu
http://jsfiddle.net/mcepc44p/2/
führt.
Links zu Links gemacht - Rolf B
Hallo Raketensuchgerät,
Pardon. Das war der falsche Link.
Sollte der hier sein
https://stackoverflow.com/questions/25753754/canvas-todataurl-security-error-the-operation-is-insecure
Ist aber auch kein Link.
Links kannst du zum Beispiel erzeugen, indem du den Linktext in spitze Klammern einschließt. So machst du es für den Leser etwas einfacher und bequemer.
Bis demnächst
Matthias
Hm. Also das hier geht offenbar...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="MyCanvas" width="200" height="200"></canvas><br>
<a id="FakeButton">Save Image</a>
<script>
var theCanvas = document.getElementById("MyCanvas").getContext("2d");
var theButton = document.getElementById("FakeButton");
var image = new Image();
image.src = "https://i.chzbgr.com/maxW500/1691290368/h07F7F378/"
image.crossOrigin = "anonymous"; // This enables CORS
image.onload = function (event) {
try {
theCanvas.drawImage(image, 0, 0, 200, 200);
theButton.download = "cat.png";
console.log(theCanvas.canvas.toDataURL());
theButton.href = theCanvas.canvas.toDataURL();
} catch (e) {
alert(e);
}
};
</script>
</body>
</html>
Edit Rolf B: Dieser Beitrag wurde als möglicher Verstoß gegen Lizenzbestimmungen gemeldet und eine Herkunft bei StackOverflow behauptet.
Wenn das zutrifft, unterliegt der Code in diesem Posting der CC BY-SA 3.0 Lizenz. Der gepostete Code weicht in Kleinigkeiten von diesem Stackoverflow-Beitrag von StephenKC ab.
Die CC BY-SA 3.0 Bedingungen (Attributierung und Verlinkung der Lizenz) sollten damit erfüllt sein und ich stelle die Moderationsmeldung auf „erledigt“.
Hallo Raketenwilli,
ja das geht, obwohl mir das auch noch nicht schlüssig ist. Es geht aber nicht wenn die URL zu einem anderen Bild führt.
bsp.
image.src = "https://www.w3schools.com/tags/img_the_scream.jpg"
Gruss
Henry
Es geht aber nicht wenn die URL zu einem anderen Bild führt.
Ja. Sieht so aus.
Beim Abruf von https://www.w3schools.com/tags/img_the_scream.jpg wird mit der Grafik im HTTP-Header kein CORS-Header gesendet, Beim Abruf von: https://i.chzbgr.com/maxW500/1691290368/h07F7F378/hingegen:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Ohne CORS-Header blockiert der Browser das Laden der Grafik.
Wenn Du einen Apache mit aktiven mod_headers und erlaubter htaccess hast, dann kannst Du das mit
<Files "cat\.png">
Header set Access-Control-Allow-Origin "*"
</Files>
oder mit FilesMatch in der .htaccess erledigen.
Hallo Raketenwilli,
nimm doch mal kurz Stellung zu der Moderationsmeldung. Kam der Code von Stackoverflow? Ich hab parallel intern die Frage gestellt, wie wir mit Inhalten die unter Creative Commons Lizenz stehen generell umgehen; da bin ich etwas uninformiert.
Rolf
Kam der Code von Stackoverflow?
Ja. Ich habe den Kern des verlinkten Codes für das Testbeispiel sinnvoll abgeändert und benutzt.
Wenn die Webseite und die Grafik vom selben HTTP-Host stammen, dann ist das Setzen eines CORS-Headers nicht notwendig:
Test: https://home.fastix.org/Tests/canvas_download.html
Hallo Raketenwilli,
Ohne CORS-Header blockiert der Browser das Laden der Grafik.
Ja das wäre ein Problem, aber irgendwie blicke ich gar nicht mehr durch. Habe mittlwerweile alle möglichen Szenarien durchgespielt, deren Ansätze im Netz vertreten sind. Sogar, obwohl das nicht meine Wunschvorstellung war, mit Requests und da bin ich dann überrascht, dass es sogar da Proleme gibt, je nach URL. Guckst du hier.
Gruss
Henry
Sogar, obwohl das nicht meine Wunschvorstellung war, mit Requests und da bin ich dann überrascht, dass es sogar da Proleme gibt, je nach URL
Ja und du wirst mit Javascript im Browser eher nicht herausbekommen, warum vom Host "www.w3schools.com" keine Grafik von "cdn.pixabay.com" abgeholt werden kann oder mit einem solchen Referenz nicht abgeholt werden können soll. Womöglich ist das ja Absicht...
Außerdem ist meinem trüben Augen folgendes aufgefallen:
Beim direkten Abruf des Kompasses von https://cdn.pixabay.com/photo/2013/07/12/14/42/compass-148617_1280**.png**
erhalte ich mit den Anwortheadern das hier:
content-type: image/webp
Du wirst immer auf "schwer durchschaubare" Probleme stoßen wenn Du auf (das Fiddle) oder mit Daten von fremden Hosts (cdn.pixabay.com) arbeitest.
Nachtrag
Ich habe "https://home.fastix.org/Tests/200x200.png" zu Deinem Fiddle hinzugefügt. Der Abruf klappt auch laut logfile:
95.116.87.158 - - [19/Feb/2021:10:46:27 +0000] "GET /Tests/200x200.png HTTP/1.1" 200 8277 "https://tryit.w3schools.com/tryit_view.php?x=0.9969626945230762" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:85.0) Gecko/20100101 Firefox/85.0"
Trotzdem kommt die Fehlermeldung „TypeError: NetworkError when attempting to fetch resource.“ - aus Deiner Zeile alert(error)
.
In der Brwoserkonsole des Mozilla steht dann:
Quellübergreifende (Cross-Origin) Anfrage blockiert: Die Gleiche-Quelle-Regel verbietet das Lesen der externen Ressource auf https://home.fastix.org/Tests/200x200.png. (Grund: CORS-Kopfzeile 'Access-Control-Allow-Origin' fehlt).
Also bleibt es auch hier dabei: Gleicher Server oder Du sendest mit der Grafik einen passenden „Access-Control-Allow-Origin“-Header.
Das Zeug wurde ja nicht erfunden, um im Browser einfach umgehbar zu sein. Es sei denn Du baust einen serverseitigen Proxy, der die Grafik(en) abholt und mit passenden Headern weitersendet.
Es sei denn Du baust einen serverseitigen Proxy,
wobei aber sehr vorsichtig sein solltest. Nicht dass dieser Proxy dann für allerhand unschöne Dinge (z.B. Angriffe auf Webseiten Dritter) missbraucht werden kann…
Ich habe "https://home.fastix.org/Tests/200x200.png" zu Deinem Fiddle hinzugefügt.
Geändertes Fiddle:
https://www.w3schools.com/code/tryit.asp?filename=GNT3EM9UYGM9
Hallo Raketenwilli,
Das Zeug wurde ja nicht erfunden, um im Browser einfach umgehbar zu sein.
Mag sein.
Es sei denn Du baust einen serverseitigen Proxy, der die Grafik(en) abholt und mit passenden Headern weitersendet.
Darauf wird es wohl leider hinaus laufen müssen. Danke.
Gruss
Henry
Was willst Du eigentlich im Endeffekt erreichen?
Fremde Grafiken verabeiten und zum Download anbieten? Das ist technisch und juristisch „höchst heikel“.
Hallo Raketenwilli,
Was willst Du eigentlich im Endeffekt erreichen?
Fremde Grafiken verabeiten und zum Download anbieten?
du solltest mich besser kennen, bin ja nicht erst seit gestern hier.
Gruss
Henry
du solltest mich besser kennen, bin ja nicht erst seit gestern hier.
Nein. Ich habe keine Ahnung was Du erreichen willst.
Dein gezeigter Problemfall hat aber doch genau diese Funktionen: Grafik von einem Dir nicht gehörendem (das Du die CORS-Header nicht setzen kannst verursacht ja das Problem) Server abholen, in Canavas (mit bestimmter Größe) einbinden und dann wieder aus diesem (in der neuen Größe, mit 96dpi) auslesen, zum Downlad anbieten.
Ich habe also "fremde Grafiken verarbeiten und zum Download anbieten" gesehen und sicherheitshalber nachgefragt, weil ich außer dem was ich sehe eben nichts weiß.
Tagtäglich stolpern in Deutschland dutzende Leute in irgend eine Abmahnfalle: Ich denke deshalb es ist OK (und auch mit keinem Vorwurf verbunden!) wenn ich zur Vorsicht mahne. Und im Hinblick auf meinen speziellen Background als „oft krass unterschätzter Freizeitjurist“ fühle ich mich auch irgendwie berufen…
Hallo Raketenheino,
du solltest mich besser kennen, bin ja nicht erst seit gestern hier.
Nein. Ich habe keine Ahnung was Du erreichen willst.
Das weist du nicht, aber…
Fremde Grafiken verabeiten und zum Download anbieten?
… eine logische Denkweise würde konstatieren: "Das kann der nicht vorhaben, der wüsste wie das mit PHP oder sonstwas leicht zu bewerkstelligen wäre"
Dein gezeigter Problemfall hat aber doch genau diese Funktionen: Grafik von einem Dir nicht gehörendem (das Du die CORS-Header nicht setzen kannst verursacht ja das Problem) Server abholen, in Canavas (mit bestimmter Größe) einbinden und dann wieder aus diesem (in der neuen Größe, mit 96dpi) auslesen, zum Downlad anbieten.
Ja, es geht um Möglichkeiten der Veränderungen bei Mediendateien. Dabei interessiert mich, wie der rote Faden meiner letzen Threads zeigt, insbesondere die Machbarkeit und daraus Erkenntnisse für "eventuelle" Inspirationen zu ziehen.
Ich habe also "fremde Grafiken verarbeiten und zum Download anbieten" gesehen und sicherheitshalber nachgefragt, weil ich außer dem was ich sehe eben nichts weiß.
Hättest du nett, ohne subtile Anschuldigungen gefragt, hätte ich dir folgendes gesagt: Im Moment habe ich einige Anwendungen die darauf basieren eine Mediendatei hochzuladen (nur im Browser ohne Server) un diese zu verändern und dann erst zum Server zu laden. Dazu gehören Bildmanipulation, Videobildextrahierung, usw. Der Hauptzweck zur Initialisierung war vor allem, dass viele ihre riesengrossen (Dimensionen und Dateigrösse) Handy/Kamera-Bilder/Videos uploaden und nicht mal wissen, welche Datenlast sie da eigentlich umgehen können. Landet dann irgendwann auf dem Server um dort dann doch (bestenfalls) wieder verkleinert zu werden.
Mit dem anfänglichen Erfolg wuchs das Interesse zu wissen was noch machbar ist. Ein Problem, was ich aus meinem Umfeld kenne, sind Personen (sogenannte Influencer) die hunderte, manche tausende Videos und Bilder in den bekannten SocialMedia Plattformen haben. Oft benötigen diese alte Dateien, dann passiert Folgendes: Runterladen, Mediensoftware öffnen, Datei dort einladen, speichern oder wieder irgendwo hochladen. Meine Idee war jetzt, zumindest die Prozedur, wenn schon nicht die Datenlast, zu minimieren.
Das ich dies natürlich auch anders machen kann war klar, aber da ich schon mal ein Tool für lokale Dateien habe, war der Gedankengang naheliegend, dass ich das über Canvas realisieren könnte. Daher die Frage hier und offensichtlich geht das ja ohne serverseitige Technik nicht. Aber ich habe Erkenntnisgewinn.
Und im Hinblick auf meinen speziellen Background als „oft krass unterschätzter Freizeitjurist“ fühle ich mich auch irgendwie berufen…
Darüber mag man geteilter Meinung sein.
Gruss
Henry
Also einfache Grafikverarbeitung für Unbedarfte? Hm. Also unter Linux würde ich mir über
Gedanken machen. Da lässt sich ohne Browserhindernis ganz leicht was skripten. Nur haben die Insolvenzer, pardon Influenzer, eher kein Linux sondern irgendwas mit i, oder Android-Tablets.
Oder war es Bedingung, dass die Datei aus dem Web geladen werden kann? Fratzenbuch, Instagram, Pinterest und co und auch CMS wie Wordpress haben doch auch eigene, fest verstrickte Tools, die das hoch geladene Zeug ohne Zutun der Nutzer verkleinern?
Oder verstehe ich was falsch?
Hallo,
andere Frage in dem Zusammenhang.
Erstaunlicherweise, lassen sich sogar Green-Screen Anwendungen mit Canavas realisieren. Das funktioniert auch. Ich frage mich allerdings warum nur wenn ich das auf dem Server lade? Lokal eben nicht.
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Manipulating_video_using_canvas
unten auf der Seite befindet sich auch ein Link zum Fullcode (unterscheidet sich geringfügig, habe beides probiert) und den Mediendateien.
Gruss
Henry
processor.js:29 Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
at Object.computeFrame (file:///tmp/chroma-keying/processor.js:29:29)
at Object.timerCallback (file:///tmp/chroma-keying/processor.js:6:12)
at HTMLVideoElement.<anonymous> (file:///tmp/chroma-keying/processor.js:23:16)
Das ist die Zeile 29:
let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
Vielleicht geht man davon aus, dass der Videostream von einer lokal angeschlossenen Kamera stammt (Linux behandelt Geräte wie Dateien …) und will also die Weitergabe von solchen ins Web tunlichst verhindern.