Canvas および File API_html5 チュートリアル スキルを使用した画像のズームとアップロードの完全な例

WBOY
リリース: 2016-05-16 15:49:07
オリジナル
1541 人が閲覧しました

アドレスの例: キャンバス サイズ変更デモ
原著者: Tom Trenka 博士
オリジナルの日付: 2013 年 8 月 6 日
翻訳日: 2013 年 8 月 8 日

Tom Trenka 「私の」ブログに記事を書くことができて大変光栄です。トムは Dojo フレームワークの最初の貢献者の 1 人であり、SitePen での私の指導者でもあり、彼の天才性を最高レベルで目の当たりにしました。彼は常に多くの困難な問題をいち早く予測し、前向きな解決策を示していました。彼は常に外側から考え、型破りだが確かな方法で周辺問題を解決します。この記事はその完璧な例です。
最近、ユーザーが画像を (とりわけ) サーバーにアップロードし、当社がサポートする多数の Web サイトのクライアント側で使用できるようにするユーザー インターフェイス API の作成についてよく質問されます。通常、これは非常に簡単です。フォームを作成し、ファイルの種類の入力ボックスを追加し、ユーザーがコンピューターから画像を選択できるようにし、フォーム タグのプロパティで enctype="multipart/form-data" フォームを設定してアップロードします。 。とてもシンプルですね。実際、これは非常に単純な例です。クリックして入力
画像をアップロードする前に何らかの方法で前処理したい場合はどうすればよいでしょうか。たとえば、最初に画像サイズを圧縮する必要がある場合、または画像を png や jpg などの特定の種類の形式のみにする必要がある場合、どうすればよいでしょうか。
キャンバスを使用して問題を解決してください!

Canvas の概要
Canvas は、ユーザーが通常 JavaScript を使用してページ上に直接グラフィックを描画できるようにする HTML5 の新しい DOM 要素です。たとえば、SVG はラスター API (ラスター API) ですが、VML は描画には Adob​​e Illustrator (ベクター) を使用し、描画には Adob​​e Photoshop (ラスター) を使用することを検討できます。

キャンバス上でできることは、画像の読み取りとレンダリングであり、JavaScript を介して画像データを操作できるようになります。主にさまざまな画像フィルタリング技術に焦点を当てて、基本的な画像処理を説明する既存の記事が多数ありますが、必要なのは画像を拡大縮小して特定のファイル形式に変換することだけであり、Canvas はこれらの作業を完全に行うことができます。

元の画像の高さがどんなに高くても、画像の高さが 100 ピクセルを超えないなど、当社が想定する要件。基本的なコードは次のとおりです:

コードをコピーします
コードは次のとおりです:

// パラメータ、最大高さ
var MAX_HEIGHT = 100;
// レンダリング
function render(src){
// Image オブジェクトを作成します
var image = new Image() ;
// ロードイベントハンドラーをバインドし、ロード完了後に実行します
image.onload = function(){
// キャンバス DOM オブジェクトを取得します
var Canvas = document.getElementById("myCanvas ");
// 高さが標準を超える場合
if(image.height > MAX_HEIGHT) {
// 幅比例拡大縮小 *=
image.width *= MAX_HEIGHT / image.height ;
image.height = MAX_HEIGHT;
}
// Canvas の 2D 環境オブジェクトを取得します。
// Context が管理者であり、Canvas がハウスであることがわかります。 ctx = Canvas.getContext("2d");
//キャンバス画面をクリア
ctx.clearRect(0, 0, Canvas.width, Canvas.height);//キャンバスの幅と高さをリセット
canvas.width = image.width;
canvas.height = image.height;
// キャンバスに画像を描画します
ctx.drawImage(image, 0, 0, image.width, image .height);
// !!! 画像は dom
} に追加されないことに注意してください。src 属性を設定すると、ブラウザーが自動的に読み込みます。
// src 属性を設定する前に、まずイベントをバインドする必要があることに注意してください。そうしないと、同期の問題が発生します。
画像.src =
};
上記の例では、canvas の toDataURL() メソッドを使用して、Base64 でエンコードされた画像の値を取得できます (これは、同様に 16 進文字列、またはバイナリ データ ストリームとして理解できます)。
注: Canvas の toDataURL。 () 取得された URL は文字列で始まり、「data:image/png;base64」という 22 個の無駄なデータが含まれており、クライアントまたはサーバーでフィルタリングする必要があります。
原則として、ブラウザがサポートしている限り、 URL アドレス 長さに制限はありません。1024 という長さの制限は、旧世代の IE に固有のものです。

すみません、必要な画像を入手するにはどうすればよいですか?
いい子、質問してよかったです。ファイル入力ボックスを介して直接処理することはできません。このファイル入力ボックス要素から取得できるのは、ユーザーが選択したファイルへのパスのみです。従来の想像によれば、このパス パス情報を通じて画像を読み込むことができますが、これはブラウザーでは非現実的です。 (翻訳者注: ブラウザのメーカーは、市場シェアを獲得し、少なくともメディア攻撃を回避するために、ブラウザが絶対に安全であることを保証する必要があります。これが許可されると、悪意のある URL がファイル パスをつなぎ合わせて特定の機密情報を取得しようとする可能性があります。) >この要件を達成するには、HTML5 のファイル API を使用してユーザーのディスク上のファイルを読み取り、このファイルを画像のソース (src、source) として使用できます。


ファイル API の概要 新しいファイル API インターフェイスは、セキュリティ サンドボックス ルールに違反することなくユーザー ファイル ディレクトリを読み取り、リストする方法です。サンドボックスの制限により、悪意のある Web サイトはユーザー ディスクにウイルスを書き込むことができず、もちろん実行することもできません。
使用したいファイル読み取りオブジェクトは FileReader と呼ばれます。FileReader を使用すると、開発者はファイルの内容を読み取ることができます (特定のブラウザの実装は大きく異なる場合があります)。

画像ファイルのパスを取得したと仮定し、前のコードに依存すると、FileReader を使用して画像をロードしてレンダリングすることが簡単になります。


コードをコピーコードは次のとおりです:
// 画像ファイル (URL パス) を読み込みます
function loadImage(src) {
/ / 画像タイプ以外のファイルを除外します
if(!src.type.match(/image.*/)){
if(window.console){
console.log( "選択されたファイルの種類は画像ではありません: ", src.type);
window.confirm("画像ファイルのみ選択できます");
}
// FileReader オブジェクトを作成し、レンダリング関数を呼び出してレンダリングを完了します。
var Reader = new FileReader();
// ロード イベントの自動コールバック関数をバインドします。
reader.onload = function (e){
/ / 前のレンダリング関数を呼び出します
render(e.target.result);
// ファイルの内容を読み取ります
reader.readAsDataURL(src);
};


すみません、ファイルを入手するにはどうすればよいですか?
小さな白いウサギ、辛抱してください!次のステップはファイルを取得することです。もちろん、これを行う方法はたくさんあります。たとえば、テキスト ボックスを使用してユーザーがファイル パスを入力できるようにすることもできますが、明らかにほとんどのユーザーは開発者ではないため、どのような値を入力すればよいのかわかりません。
ユーザーの利便性を考慮して、ドラッグ アンド ドロップ API インターフェイスを使用します。 。

ドラッグ アンド ドロップ API の使用

ドラッグ アンド ドロップ インターフェイス (ドラッグ アンド ドロップ) は非常に簡単です。ほとんどの DOM 要素で、イベント ハンドラーを実装にバインドできます。ユーザーがディスクから dom オブジェクトにファイルをドラッグしてマウスを放すと、ファイルを読み取ることができます。コードは次のとおりです:



コードをコピー
コードは次のとおりです: function init(){ // DOM 要素オブジェクトを取得します
var target = document.getElementById("drop-target");
// ドラッグオーバー (DOM 要素の上にドラッグする) イベント配信を防止します
target.addEventListener("dragover ", function(e){e.preventDefault();}, true);
// マウスイベントをドラッグして放します
target.addEventListener("drop", function(e ){
// デフォルトのイベントとイベントの伝播を防止します
e.preventDefault();
// 前のイメージ読み込み関数を呼び出します。パラメータは dataTransfer オブジェクトの最初のファイルです
loadImage(e .dataTransfer.files[ 0]);
}, true);
var setheight = document.getElementById("maxheight"); setheight.addEventListener(" click", function(e){
//
var value = maxheight.value;
if(/^d $/.test(value)){
MAX_HEIGHT = parseInt(value);
e.preventDefault();
var btnsend = document.getElementById("btnsend"); ", function(e ){
//
sendImage();
},true);
};


プレビュー画像の表示など、その他の処理も行うことができます。ただし、画像を圧縮したくない場合は、おそらく役に立ちません。 Ajaxを使用して、HTTPポストメソッドで画像データをアップロードします。次の例では、Dojo フレームワークを使用してリクエストを完了します。もちろん、
Dojo コードは次のとおりです。

コードをコピー
コードは次のとおりです:

// 翻訳者は Dojo を理解していないため、jQuery 実装は後で添付します
/ / DTK 1.7 は AMD であることに注意してください!
require(["dojo/request"], function(request){
// リクエスト URL、パラメータ、コールバックを設定します。
request.post("image -handler.php", {
data: {
imageName: "myImage.png",
imageData: encodeURIComponent(document.getElementById("canvas").toDataURL("image/png"))
}
} ).then(function(text){
console.log("サーバーが返しました: ", text);
}); >
jQuery は次のように実装されます:



コードをコピーします
コードは次のとおりです:
// 画像、jQuery バージョンをアップロードします
function sendImage(){
// キャンバス DOM オブジェクトを取得します
var Canvas = document.getElementById("myCanvas");
// Get Base64 でエンコードされた画像データ、形式は string
// "data:image/png;base64," の先頭はクライアントまたはサーバー側で削除する必要があり、次の部分を記述できますファイルに直接コピーします。
var dataurl = Canvas.toDataURL("image/png");
// セキュリティのために URI をエンコードします
// data:image/png;base64、始まり
var imagedata = encodeURIComponent( dataurl) ;
//var url = $("#form").attr("action");
// 1. フォームの処理が難しい場合は、非表示の隠しフィールドを使用してリクエストを設定できます。アドレス
//
var url = $("input[name='action']").val ();
// 2. DOM オブジェクトの属性を直接使用して
// を取得することもできます。
// var url = $("#imageaction").attr("action");
// 文字列であるため、サーバーはデータのトランスコード、ファイル操作などを行う必要があります。
// 個人的な同意、http パラメータ名はすべて小文字です
console.log(dataurl);
var data = {
imagename: " myImage .png",
imagedata: imagedata
};
jQuery.ajax( {
url : url,
data : data,
type : "POST",
/ / 期待される戻り値の型
dataType: "json",
complete : function(xhr,result) {
//console.log(xhr.responseText);
var $tip2 = $( "#tip2");
if(!xhr){
$tip2.text('ネットワーク接続に失敗しました!');
return false;
var text = xhr.responseText ;
if(!text){
$tip2.text('ネットワークエラー!');
return false;
var json = eval("(" text ")" );
if(!json){
$tip2.text('解析エラー!');
return false;
$tip2.text(json.message) ;
}
//console.dir(json)
}
}; 🎜>
はい、完了しました!必要なのは、画像のサイズを制御できるシンプルなユーザー インターフェイスを作成することだけです。サーバーにアップロードされたデータは、multi-part/form-data の enctype を処理する必要はありません。
完全なコード例を次に示します。





コードをコピーします

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

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
文字列パス = request.getContextPath();
StringbasePath = request.getScheme() "://" request.getServerName() ":" request.getServerPort() パス "/";
%>



キャンバスおよびファイル API 経由で上に送信された画像







// パラメータ、最大高さ
var MAX_HEIGHT = 100;
// 渲染
function render(src){
// 创建一个 Image 对象
var image = new Image();
// 绑定loadイベント处理器、追加完了後実行
image.onload = function(){
// Canvas DOM对象の取得
var Canvas = document.getElementById("myCanvas") ;
// 如果高超标
if(image.height > MAX_HEIGHT) {
// 宽度等比缩放 *=
image.width *= MAX_HEIGHT / image.height;
画像.高さ = MAX_HEIGHT;
}
// Canvas の 2D 環境オブジェクトを取得します。
// 理解できる Context は管理员、canvas は房子
var ctx = Canvas.getContext("2d");
// Canvas清屏
ctx.clearRect(0, 0, Canvas.width, Canvas.height);
// 重置canvas宽高
canvas.width = image.width;
canvas.height = image.height;
// 画像をキャンバス上に展開
ctx.drawImage(image, 0, 0, image.width, image.height);
// !!! 注意,画像はdom之中に追加されていません
};
// src プロパティを設定します。視聴者は自動的に追加します。
// 事前に決定する必要があるイベントを認識します。src プロパティを設定できないと、同期問題が発生する可能性があります。
image.src = src;
};
// 追加画像文件(url路径)
functionloadImage(src){
// 非画像型文件
if(!src.type.match(/image.*/ )){
if(window.console){
console.log("选择的文件型不是图片: ", src.type);
} else {
window.confirm("只能选择图片文件");
}
戻る;
}
// 创建 FileReader 对オブジェクト 并调用 render 関数数来渲染を完了します。
var リーダー = new FileReader();
// 绑定loadイベント自動回调関数数
reader.onload = function(e){
// 前のレンダリング関数数
render(e.target.result);
};
// 文件内容の读取
reader.readAsDataURL(src);
};
// 上传图片,jQuery 版
function sendImage(){
// キャンバス DOM 对象を取得
var Canvas = document.getElementById("myCanvas");
//Base64 暗号化後の画像データを取得します。形式は文字列です。
// "data:image/png;base64," は、ゲスト端末またはサービス端末で削除する必要があり、後ろの部分は直接削除できます。
var dataurl = Canvas.toDataURL("image/png");
// 安全な对URI进行编码
// data:image/png;base64, 开头
var imagedata = encodeURIComponent(dataurl);
//var url = $("#form").attr("action");
// 1. 如果形式表单不好処理、设求地址を設定するには特定の隠しフィールドを使用できます
//
var url = $("input[name='action']").val();
// 2. 特定のdomオブジェクトのプロパティを直接使用して取得することもできます。
//
// var url = $("#imageaction").attr("action");
// 文字列であるため、サーバーはデータの転送や文書操作などを行う必要があります。
//console.log(画像データ);
var data = {
画像名: "myImage.png",
画像データ: 画像データ
};
jQuery.ajax( {
url : url,
data : data,
type : "POST",
// 期待される戻り值类型
dataType: "json",
complete : function(xhr,result) {
//console.log(xhr.responseText);
var $tip2 = $("#tip2");
if(!xhr);
$tip2.text('网络接失败!');
return false;
}
if(!text){
$tip2 .text('网络错误!');
return false;
var json = eval("(" text ")"); tip2.text('解析错误!');
return false;
$tip2.text(json.message);
//console.dir(json) );
//console.log(xhr.responseText)
}
});
};
function init(){
// 获取DOM元素对象
var target = document.getElementById("drop-target");
// ドラッグオーバー (DOM 要素の上にドラッグ) イベント配信を防止します
target.addEventListener("dragover", function(e){e.preventDefault( ) ;}, true);
// マウスイベントをドラッグして放します
target.addEventListener("drop", function(e){
// デフォルトのイベントとイベントの伝播を防止します
e.preventDefault ();
// 前のイメージ読み込み関数を呼び出します。パラメータは dataTransfer オブジェクトの最初のファイル
loadImage(e.dataTransfer.files[0])、
; >var setheight = document.getElementById("setheight");
var maxheight = document.getElementById("maxheight");
setheight.addEventListener("click", function(e){
//
var value = maxheight.value;
if(/^d $/.test(value)){
MAX_HEIGHT = parseInt(value);
e.preventDefault( ); 🎜>},true);
var btnsend = document.getElementById("btnsend");
btnsend.addEventListener("click", function(e){
//
sendImage();
},true);
window.addEventListener("DOMContentLoaded", function() {
//
init();
}, false) ; >

キャンバスとファイル API を使用して画像をアップロードします >

写真を下のボックスにドラッグすると、キャンバスと JavaScript が自動的に拡大縮小されます。

input type="text" id=" maxheight" value="100"/>



画像ファイルをここにドラッグします...


id="プレビュー" style="background:#f4f4f4;width:400px;height:200px;min-height:100px;min-width:200px;">
;/canvas>


サーバー ページ、receive.jsp





コードをコピー


コード 次のように:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="sun.misc.BASE64Decoder"%>
<%@page import="java.io.*"%>
<%@page import="org.springframework.web.util.UriComponents"%>
<%@page import="java.net.URLDecoder"%>
<%!
// 本文件:/receive.jsp
// 图片存放路径
String photoPath = "D:/blog/upload/photo/";
File photoPathFile = new File(photoPath);
// references: http://blog.csdn.net/remote_roamer/article/details/2979822
private boolean saveImageToDisk(byte[] data,String imageName) throws IOException{
int len = data.length;
//
// 写入到文件
FileOutputStream outputStream = new FileOutputStream(new File(photoPathFile,imageName));
outputStream.write(data);
outputStream.flush();
outputStream.close();
//
return true;
}
private byte[] decode(String imageData) throws IOException{
BASE64Decoder decoder = new BASE64Decoder();
byte[] data = decoder.decodeBuffer(imageData);
for(int i=0;i{
if(data[i]<0)
{
//调整异常数据
data[i] =256;
}
}
//
return data;
}
%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() "://" request.getServerName() ":" request.getServerPort() path "/";
%>
<%
//如果是IE,那么需要设置为text/html,否则会弹框下载
//response.setContentType("text/html;charset=UTF-8");
response.setContentType("application/json;charset=UTF-8");
//
String imageName = request.getParameter("imagename");
String imageData = request.getParameter("imagedata");
int success = 0;
String message = "";
if(null == imageData || imageData.length() < 100){
// 数据太短,明显不合理
message = "上传失败,数据太短或不存在";
} else {
// 去除开头不合理的数据
imageData = imageData.substring(30);
imageData = URLDecoder.decode(imageData,"UTF-8");
//System.out.println(imageData);
byte[] data = decode(imageData);
int len = data.length;
int len2 = imageData.length();
if(null == imageName || imageName.length() < 1){
imageName = System.currentTimeMillis() ".png";
}
saveImageToDisk(data,imageName);
//
success = 1;
message = "上传成功,参数长度:" len2 "字符,解析文件大小:" len "字节";
}
// 后台打印
System.out.println("message=" message);
%>
{
"message": "<%=message %>",
"success": <%=success %>
}
ソース:php.cn
前の記事:HTML5 ファイルを使用して、base64 を image_html5 に変換するチュートリアル スキル 次の記事:HTML5 の新しいフォーム要素 (datalist/keygen/output) の使用方法の概要_html5 チュートリアル スキル
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
最新の問題
関連トピック
詳細>
人気のおすすめ
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート