質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.82%

JavascriptでJPEGをPNGにしたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,865

kokawa2003

score 170

javascriptでhttp://hogehoge.Jpgのuint8arrayをpngに変換する必要に迫られまして、下記コードを書きました。

                function loadImg(imgUrl) {
                    var xhr = new XMLHttpRequest();
                    xhr.open('GET', imgUrl, true);
                    xhr.responseType = "arraybuffer";
                    xhr.onload = function() {
                        var bytes = new Uint8Array(this.response);
                        console.log("uint8jpg:"+bytes);
                        var blob = new Blob([ bytes ], { type: "image/jpeg" });
                        console.log('blob:'+blob);
                        window.createImageBitmap(blob)
                        .then(function(image) {
                            var width = image.width;
                            var height = image.height;
                            console.log('ok'+image);
                            var canvas = document.createElement('canvas');
                            canvas.width  = width;
                            canvas.height = height;

                            // Draw Image
                            var ctx = canvas.getContext('2d');
                            ctx.drawImage(image, 0, 0);
                            var pngdata=canvas.toDataURL("image/png");
                            console.log('w,h:'+width+','+height);
                            var BASE64_MARKER = ';base64,';
                            var base64Index = pngdata.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
                            var base64 = pngdata.substring(base64Index);
                            var raw = window.atob(base64);
                            var rawLength = raw.length;
                            var array = new Uint8Array(new ArrayBuffer(rawLength));
                            for(i = 0; i < rawLength; i++) {
                                array[i] = raw.charCodeAt(i);
                            }
                            hogehoge......
                        })

                    };
                    xhr.send();
                };


このコードなのですがfirefox,chromeでは動くがsaferiではだめだった。
理由を調べるとwindow.createImageBitmap(blob)でundefinedで落ちてた。
でさらに調べると
ImageBitmapがsafariではつかえないらしい。
https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap
ということは多分サファリでは他の関数で代用できるとおもわれますが
どうするのが正解か分かる人はいませんか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

Lhankor_Mhyさんのコメントで紹介されているpolyfillが実際にやっているとおりではあるのですが、一度<img>要素に画像を読み込めばcreateImageBitmapを使わずに済むと思います。

function loadImg(imgUrl) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', imgUrl, true);
  xhr.responseType = "arraybuffer";
  xhr.onload = function() {
    var bytes = new Uint8Array(this.response);
    console.log("uint8jpg:"+bytes);
    var blob = new Blob([ bytes ], { type: "image/jpeg" });
    console.log('blob:'+blob);

    var objUrl, img = new Image();          // 変更箇所
    img.onload = function(image) {  // 変更箇所

      var width = image.width;
      var height = image.height;
      console.log('ok'+image);
      var canvas = document.createElement('canvas');
      canvas.width  = width;
      canvas.height = height;

      // Draw Image
      var ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0);
      URL.revokeObjectURL(objUrl);  // 変更箇所; 使い終わったobjUrlを破棄

      // 中略

    });

    objUrl = URL.createObjectURL(blob);  // 変更箇所
    img.src = objUrl;

  };
  xhr.send();
};

createImageBitmapに比べると、オブジェクトURLを作ったり破棄したりする必要があるのがデメリットでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/09 19:59

    オブジェクトURLなるものを初めて知りました。MACな人が明日くるので来たら確認します

    キャンセル

  • 2018/11/29 12:52

    今時なにって感じですが。上記コードは実は今確認したがだめだったのでなおした。
    function loadImg2(imgUrl){
    var xhr = new XMLHttpRequest();
    xhr.open('GET', imgUrl, true);
    xhr.responseType = "arraybuffer";
    xhr.onload = function() {
    var bytes = new Uint8Array(this.response);
    console.log("uint8jpg:"+bytes);
    var blob = new Blob([ bytes ], { type: "image/jpeg" });
    console.log('blob:'+blob);

    var objUrl;
    var img = new Image();
    img.onload = function()
    { // 変更箇所
    var image=img;

    try{
    var width = image.width;
    var height = image.height;
    console.log('ok'+image);
    var canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;

    // Draw Image
    var ctx = canvas.getContext('2d');
    ctx.drawImage(image, 0, 0);
    URL.revokeObjectURL(objUrl); // 変更箇所; 使い終わったobjUrlを破棄
    var pngdata=canvas.toDataURL("image/png");
    console.log('png'+pngdata);
    console.log('w,h:'+width+','+height);
    var BASE64_MARKER = ';base64,';
    var base64Index = pngdata.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
    var base64 = pngdata.substring(base64Index);
    var raw = window.atob(base64);
    var rawLength = raw.length;
    var array = new Uint8Array(new ArrayBuffer(rawLength));
    for(i = 0; i < rawLength; i++) {
    array[i] = raw.charCodeAt(i);
    }
    console.log("uint8png:"+array);
    hogehoge
    }catch(e){
    hogehoge
    }

    };

    objUrl = URL.createObjectURL(blob); // 変更箇所
    img.src = objUrl;

    };
    xhr.send();
    }

    キャンセル

  • 2018/12/04 12:06

    雑な対応になってしまい、失礼しました。とはいえ、解決したのであれば幸いです。

    キャンセル

+1

「createimagebitmap polyfill」でググったところ、こんな記事が。
createImageBitmap polyfill for Safari and Edge - DEV Community 👩‍💻👨‍💻

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.82%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る