Casablanca: Bilddownload

Hallo Forum,

ich erzeuge zur Laufzeit ein image-Element. Wenn man einen Link anklickt, soll dieses Element gedownloaded werden können. Wie kann man dies erreichen?

Gruß

  1. Hallo Forum,

    ich erzeuge zur Laufzeit ein image-Element. Wenn man einen Link anklickt, soll dieses Element gedownloaded werden können. Wie kann man dies erreichen?

    Gruß

    Ich würde es mal mit dem Event-Händler onclick versuchen.

  2. Mahlzeit,

    ich erzeuge zur Laufzeit ein image-Element. Wenn man einen Link anklickt, soll dieses Element gedownloaded werden können. Wie kann man dies erreichen?

    Du musst das Bild mit den passenden Headern an den Browser senden. Wurde schon einige male hier im Forum diskutiert und sollte im Archiv zu finden sein.
    Allerdings ist das auch nur eine Empfehlung an den Browser. Ob er das dann auch macht, ist eine Sache der Einstellungen im Browser.

    --
    42
  3. Meine Herren!

    ich erzeuge zur Laufzeit ein image-Element. Wenn man einen Link anklickt, soll dieses Element gedownloaded werden können. Wie kann man dies erreichen?

    Wie erzeugst du das Bild denn? Wenn du es zur Laufzeit erzeugst, dann benutzt du dafür bestimmt das Canvas-Element, richtig? (1)

    Das Canvas-Element hat eine Methode toDataURL() mit der du eine dataURL erzeugen kannst, das ist eine spezielle Form von URL, die für genau diese Zwecke entworfen wurde.

    Dein Link muss dann auf diese URL zeigen. Am besten gibst du dem Link noch das download-Attribut mit auf dem Weg, damit der Browse weiß, dass er das Bild nicht zu öffnen hat, sondern zum Download anbieten soll.

    1. Falls du das Canvas-Element nicht sowieso schon benutzt, kannst du für diesen Zweck ein Canvas-Element anlegen, AFAIK muss du das Element nicht einmal in das Dokument einhängen, es reicht wenn es programmatisch erreichbar ist, um damit zu arbeiten.
    --
    “All right, then, I'll go to hell.” – Huck Finn
    1. Mahlzeit,

      Wie erzeugst du das Bild denn? Wenn du es zur Laufzeit erzeugst, dann benutzt du dafür bestimmt das Canvas-Element, richtig? (1)

      Kann ja sein, das ich falsch liege, aber ein Canvas-Element hat noch nichts mit einen img-Element zu tun, oder?

      --
      42
      1. Meine Herren!

        Wie erzeugst du das Bild denn? Wenn du es zur Laufzeit erzeugst, dann benutzt du dafür bestimmt das Canvas-Element, richtig? (1)

        Kann ja sein, das ich falsch liege, aber ein Canvas-Element hat noch nichts mit einen img-Element zu tun, oder?

        Man kann das Canvas benutzen, um image-Elemente zur Laufzeit zu erzeugen, oder man kann image-Elemente benutzen, um sie auf das Canvas zu zeichnen. Letzteres hilft uns bei dem vorliegenden Problem. Ein Beispiel spricht vielleicht mehr als Tausend Worte.

        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. Mahlzeit,

          Man kann das Canvas benutzen, um image-Elemente zur Laufzeit zu erzeugen, oder man kann image-Elemente benutzen, um sie auf das Canvas zu zeichnen. Letzteres hilft uns bei dem vorliegenden Problem. Ein Beispiel spricht vielleicht mehr als Tausend Worte.

          Ok, dann war ich da schon richtig. Canvas in img geht nicht, aber umgekehrt geht in jedem Fall.
          Du lädst praktisch ein Bild in ein Canvas. Kreative Lösung, gefällt mir :)

          --
          42
    2. Hallo,

      danke. Das bild wird folgendermassen erzeugt:

        
           var imgelem = evt.data.chart.jqplotToImageElem();  
      
      

      Ich habe folgenden:

        
           var canvas = document.createElement('canvas');  
           var context = canvas.getContext('2d');  
           var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");  
           window.location.href = image;  
      
      

      Wie kann ich nun das erzeugete Image-Element einem Canvas zuweisen?

      Gruß

      1. Meine Herren!

        Wie kann ich nun das erzeugete Image-Element einem Canvas zuweisen?

        Mein spricht eigentlich nicht davon, dem Canvas-Element das Image-Element zuzuweisen. Canvas übersetzt sich mit Leinwand, wir zeichnen das Bild einfach auf diese Leinwand.

        Ich greife dein Beispiel mal auf:

        var canvas = document.createElement('canvas');  
        // Wir müssen erstmal die Dimensionen unserer Leindwand mit denen unseres Bildes abgleichen  
        canvas.height = imgelem.height;  
        canvas.width = imgelem.width;  
          
        var context = canvas.getContext('2d');  
          
        // Weil unsere Leinwand und unser Ursprungs-Bild jetzt gleich groß sind, können wir uns nun dem eigentlichen Zeichnen widmen. Wir müssen natürlich oben, links ansetzen, damit es genau passt:  
          
        canvas.drawImage( imgelem,0,0 );  
          
        // Den eigentlichen Code, um den Download zu starten, habe ich abgewandelt. Ich finde es nicht sinnvoll, von einer gewöhnlichen Seite auf einen Datei-Download weiter zu leiten. Ich benutze deshalb ein a-Element um den Download zu starten.  
          
        var image = canvas.toDataURL("image/png");  
          
        var a = document.createElement('a');  
        a.href = image;  
        a.download = 'Bildname.png';  
        a.click(); // Wir brauchen künstlichen Click, damit der Browser den Download beginnt  
          
          
        
        
        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. Meine Herren!

          canvas.drawImage( imgelem,0,0 );

          ARK! Das da sollte context und nicht canvas stehen!

          --
          “All right, then, I'll go to hell.” – Huck Finn
        2. Hi,

          vielen Dank. Ich habe den Code bei mir eingesetzt. Leider passiert da nichts, keine Reaktion! "imgelem" ist vom Typ [object HTMLImageElement]. Ich weiss es nicht, vielleicht habe ich das falsche Bildformat.

          Gruß

    3. hi,

      Das Canvas-Element hat eine Methode toDataURL() mit der du eine dataURL erzeugen kannst, das ist eine spezielle Form von URL, die für genau diese Zwecke entworfen wurde.

      DataURL ist ein Base64-String. Den würde ich nicht zum Download anbieten. Es gibt aber noch eine andere Methode für canvas:

        
              canvas.toBlob(function(blob) {  
                  saveAs(blob);  
              }, 'image/bmp', 1);  
      
      

      womit als Download auch image/jpeg oder image/png möglich sind, nähreres auf dem MDN.

      Beispiel von mir

      Ob der Umweg über canvas gegangen werden muss, hängt davon ab wie weiter oben das src-Attribut fürs Image-Objekt erzeugt wird, bzw. davon, wo für das src-Attribut die Daten herkommen.

      MfG

      1. Meine Herren!

        Das Canvas-Element hat eine Methode toDataURL() mit der du eine dataURL erzeugen kannst, das ist eine spezielle Form von URL, die für genau diese Zwecke entworfen wurde.

        DataURL ist ein Base64-String. Den würde ich nicht zum Download anbieten. Es gibt aber noch eine andere Methode für canvas:

        Stimmt, das scheint mir auch eleganter, die Browserunterstützung ist nur leider noch nicht recht mau.

        canvas.toBlob(function(blob) {
                    saveAs(blob);
                }, 'image/bmp', 1);

          
        So könnte eine schemahafte saveAs-Funktion aussehen:  
          
        ~~~javascript
        function saveAs( blob ) {  
           var a = document.createElement( 'a' );  
           a.href = URL.createObjectURL( blob );  
           a.download = 'bild.bmp';  
           a.click();  
        }
        

        Das vorgeschlagene FileSaver.js bietet eine robustere Implementation.

        womit als Download auch image/jpeg oder image/png möglich sind, nähreres auf dem MDN.

        Das ist mit daraURLs auch der Fall. Habe aber gerade nochmal in der Spezifikation nachgelesen, dass nur image/png obligatorisch für die Browser ist.

        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. hi,

          womit als Download auch image/jpeg oder image/png möglich sind, nähreres auf dem MDN.

          Das ist mit dataURLs auch der Fall.

          Ahh, wuste ich auch noch nicht, danke fürn Hinweis!

          MfG

  4. hi,

    ich erzeuge zur Laufzeit ein image-Element. Wenn man einen Link anklickt, soll dieses Element gedownloaded werden können. Wie kann man dies erreichen?

    Zum Speichern unter... nutze ich die Lib FileSaver.js, die findest Du auf dem Github.

    MfG