Skip to content

Instantly share code, notes, and snippets.

@s-hiroshi
Created November 17, 2012 12:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save s-hiroshi/4095694 to your computer and use it in GitHub Desktop.
Save s-hiroshi/4095694 to your computer and use it in GitHub Desktop.
JavaScript > Canvas要素に描画した画像の回転
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>キャンバス画像の回転サンプル</title>
<link rel="stylesheet" href="bootstrap.min.css" media="all">
<link rel="stylesheet" href="bootstrap-responsive.min.css" media="all">
<link rel="stylesheet" href="rotate.css" media="all">
<script src="jquery-1.8.2.min.js"></script>
<script src="bootstrap.min.js"></script>
<script src="rotate.js"></script>
</head>
<body>
<div class="container" style="margin-top: 1em;">
<p>canvas要素に描画した画像の回転。</p>
<!-- メインコンテンツ -->
<div class="row">
<!-- ファイルアップロード -->
<div id="upload-wrapper"><input id="upload" name="upload" type="file" value="File Upload"></div>
<div id="view" class="view">
<p style="color: white; font-size: 2em; line-height: 428px; text-align: center">画像をドラッグ&amp;ドロップしてください。</p>
</div>
<div class="tuple">
<button id="rotate" class="btn btn-large btn-info">右90度回転</button>
</div><!-- tuple -->
</div><!-- /row -->
</div><!-- /container -->
</body>
</html>
@charset "utf-8";
/**
* Copyright 2012 Sawai Hiroshi
* http://www.info-town.jp
*
*/
body {
line-height: 1.5;
}
h1 {
color: #0088CC;
}
#header {
margin-bottom: 2em;
}
#upload-wrapper {
margin-bottom: 1em;
}
.row {
margin-bottom: 2em;
}
.tuple {
margin: 1em 0;
}
.btn {
width: 170px;
}
.view {
position: relative;
height: 428px;
background: #000;
}
.num-input {
width: 44px;
}
/**
* Canvasを時計回りに90度回転
*
* @author Hiroshi Sawai <info@info-town.jp>
*/
jQuery(function($) {
var img;
var canvas = $('<canvas>').appendTo($('#view')).get(0);
var cxt = canvas.getContext('2d');
// 画像が読み込まれていればtrueを返す。読み込まれていなければアラートを表示しfalseを返す
function checkImage (img) {
if ((img.width > 0) === false ) {
alert('画像がありません。');
return false;
}
return true;
}
// 適切な画像タイプならばtrue。対応していないタイプならばアラートを表示してfalseを返す
function checkFileType(text) {
// ファイルタイプの確認
if (text.match(/^image\/(png|jpeg|gif)$/) === null) {
alert('対応していないファイル形式です。\nファイルはPNG, JPEG, GIFに対応しています。');
return false;
}
return true;
}
/*
* 画像ファイル読み込み・表示
* 画像をキャンパスへ描画する基本的な流れ
* <ul>
* <li>img要素を作成(ノードには追加しない)
* <li>img要素に画像を読込
* <li>img要素をcanvasへ描画
* </ul>
*/
// img要素から画像データを
function loadImg(width, height) {
return function() {
// 画像ファイル読込はoriginalを初期化
if (typeof width === 'undefined' || typeof height === 'undefined') {
original = null;
}
// サイズの設定
width = width || this.width;
height = height || this.height;
canvas.width = width;
canvas.height = height;
// 読込
try {
cxt.clearRect(0, 0, canvas.width, canvas.height);
cxt.drawImage(this, 0, 0, width, height);
if (original === null) {
original = cxt.getImageData(0, 0, width, height);
$('#org-width').val(width);
$('#org-height').val(height);
}
$(this).remove();
} catch (e) {
alert('画像を開けませんでした。');
}
};
}
// 画像読込ハンドラ
function readFile(reader) {
return function() {
if ($('#view p').length > 0) {
$('#view p').remove();
}
// imgへオブジェクトを読み込む
img = $('<img>').get(0);
img.onload = loadImg();
img.setAttribute('src', reader.result);
};
}
// 参照ボタンで読込処理
$('#upload').change (function() {
var file, reader;
// 選択したファイル情報
file = this.files[0];
// ファイルタイプの確認
if (checkFileType(file.type) === false) {
return false;
}
// canvasに描画
reader = new FileReader();
reader.onload = readFile(reader);
reader.readAsDataURL(file);
});
// ドラッグアンドドロップで読込
$('#view').get(0).ondragover = function() {
return false;
};
// bind('ondrop', function() {});はうまく動かなかった(2012.11.07)
$('#view').get(0).ondrop = function(event) {
var file, reader;
if (event.dataTransfer.files.length === 0) {
alert('画像を開けませんでした。');
return false;
}
// ドロップされたファイル情報
file = event.dataTransfer.files[0];
// ファイルタイプの確認
if (checkFileType(file.type) === false) {
return false;
}
// Canvasへの描画
reader = new FileReader();
reader.onload = readFile(reader);
reader.readAsDataURL(file);
// バブリング・デフォルト処理停止
event.stopPropagation();
event.preventDefault();
};
/*
* 回転
*/
function rotate(img) {
return function() {
var width = canvas.width;
var height = canvas.height;
canvas.width = height;
canvas.height = width;
cxt.clearRect(0, 0, canvas.width, canvas.height);
cxt.translate(canvas.width / 2, canvas.height / 2);
cxt.rotate(90 * Math.PI / 180);
cxt.translate(- img.width / 2, -img.height / 2);
cxt.drawImage(img, 0, 0, img.width, img.height);
};
}
// 回転
$('#rotate').click(function (event) {
var canvasData = canvas.toDataURL();
var img = $('<img>').get(0);
img.onload = rotate(img);
img.setAttribute('src', canvasData);
// バブリング・デフォルト停止
event.stopPropagation();
event.preventDefault();
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment