ホームページ >ウェブフロントエンド >jsチュートリアル >IE11 での Canvas.toDataURL を使用した互換性問題の解決策

IE11 での Canvas.toDataURL を使用した互換性問題の解決策

php中世界最好的语言
php中世界最好的语言オリジナル
2018-04-14 14:12:506689ブラウズ

今回は、IE11 で Canvas.toDataURL を使用する際の互換性の問題を解決するためのアイデアをお届けします。 。

問題が見つかりました 最近、プロジェクトでは Canvas の toDataURL メソッドを使用して、

画像

の Base64 形式データを取得し、バックグラウンドにアップロードするために使用できます。以前、キャンバスがクロスドメイン画像によって汚染され、データを取得できなくなるという落とし穴に遭遇したことがあったので、最初から CrossOrigin 属性 の値を巧みに追加しました。 コードはおおよそ次のとおりです。 これは確実だと思いましたし、Chrome ブラウザでは非常にスムーズに進みましたが、IE11 では不可解な SecurityError が発生しました:

特定のエラー メッセージはありません。プロンプトには toDataURL を実行する行が表示されるだけですが、これは非常にわかりにくいです。

IE11 での Canvas.toDataURL を使用した互換性問題の解決策

試してみる

初めてグーグルで検索したところ、多くの人がこの問題に遭遇していることがわかりましたが、有効な解決策は見つかりませんでした。 Fabric.js の使用を提案する人もいましたが、調べてみると面倒だと思いました。 caniuse では、この方法が IE11 では問題があることも明確にマークされています。 IE のバグのようだったので、国を保存する方法を考えました。画像の Base64 データを取得する方法は 1 つだけではありません。toDataURL メソッドは十分にサポートされていないため、別の方法を使用します。

まずキャンバスを BLOB に変換します

  • 次に、FileReader を使用して dataUrl を読み取ります

  • コードはおおよそ次のとおりです:

    const canvas = document.createElement("canvas");
    const context = canvas.getContext("2d");
    context.fillStyle = "black";
    context.fillRect(0, 0, canvas.width, canvas.height);
    const imageElement = document.createElement("img");
    imageElement.crossOrigin = "Anonymous";
    imageElement.onload = () => {
     context.drawImage(
     imageElement,
     params.left,
     params.top,
     canvas.width,
     canvas.height,
     0,
     0,
     canvas.width,
     canvas.height
     );
     const dataUrl = canvas.toDataURL("image/jpeg", 1);
    }
    imageElement.src = 'xxx';
    しかし、これでは役に立ちません....
今回は、msToBlob メソッドが SecurityError を報告する番でした。私:? ? ?

解決しました

実際にはセキュリティ上の理由があるようです。唯一のセキュリティ上の理由は、クロスドメイン イメージです。 IEのセキュリティポリシーが厳しくなっているのかもしれないし、を設定してもデータの読み込みはできないのではないかと思い、クロスドメインなのでクロスドメインを外してみようと考えました。要因:

ajax を使用して画像のバイナリデータの取得をリクエストします crossOrigin = "Anonymous"

  • バイナリデータをbase64形式に変換します

  • 取得したbase64データをimage要素のsrcとして設定し、キャンバスに描画します

  • 通常通り toDataURL を呼び出します

  • コードはおおよそ次のとおりです:

const reader = new FileReader();
reader.readAsDataURL(canvas.msToBlob());
reader.onloadend = () => {
 const base64data = reader.result;
};
試してみたところ、無事に目標を達成できました。

後で情報を確認したところ、キャンバスが汚染されている場合、toDataURL も toBlob も正常に実行されないことがわかりました。

欠陥

この方法でも目標は達成できますが、パフォーマンスが犠牲になります。最初に画像データをリクエストする必要があるだけでなく、データ エンコーディングの変換にも非常に時間がかかります。小さな写真は問題ありませんが、写真が大きい場合 (たとえば、3M を超える場合)、プロセス全体に最大 1 ~ 2 分かかる可能性があり、これは許容できません。

キャンバスの toDataUrl は画像を圧縮しますか?

Canvas のdrawImage メソッドを使用して画像オブジェクトをキャンバス上に描画すると、画像サイズが大幅に増加するため、PNG 形式でのみ保存できます。 toDataUrl を使用して Canvas を Base64 に変換します。encoderOptions を 1 に設定しても、画像は大幅に縮小されますが、それでも元の画像よりは大きくなります。 encoderOptions がデフォルトの 0.92 を使用する場合、最終的な画像サイズは初期のものと同様になります

この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、PHP に関する他の関連記事に注目してください。中国語のサイトです!

推奨読書:

Angular4の入出力の使い方

easyuiのドロップダウンボックスの動的カスケードロードの実装方法(コード付き)

以上がIE11 での Canvas.toDataURL を使用した互換性問題の解決策の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。