From window, to wind

趣味のゲームとJavaプログラムなどについて 適当に書き綴るブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

HTML5のCanvasで画像表示(嘘)

えーと、タイトルにある通り嘘ですw

HTML5のCanvasを使っているのですが、
画像をJavaScriptで1ピクセルずつ四角形で塗りつぶしています。
(普通は画像ファイルを読み込んで描画)

ですのでファイルサイズがとっても大きいです(スクリプトのコード中に画像データが埋め込まれていると考えてください)。開く際はご注意を・・・
http://kagenyan.web.fc2.com/canvastest/canvastest.htm

このファイルを作る際に利用したツールのソースコードを置いておきます。
もともとはHTMLのテーブルタグで画像を表示するために作ったツールを流用した物なので、
テーブルタグ生成のコードも含まれているので、テーブルタグで描画したい人は
そちらをご利用してください(たぶんいない)。

ファイルサイズ的には Canvas > テーブルタグ ですねw

なお、このツールではプログレスバーは計算時間だけなので、
計算終了後コードをテキストボックスに表示するのに時間がかかるのでご注意ください。

まあ誰得って奴ですねw

【追記】
ファイルサイズが大きいのと処理が遅い原因として
ピクセルの書きだしのコードが一つ一つ埋め込まれていることにあります。

そこで画像のRGBデータを配列として、
for文で回すことにしました。
ファイルサイズもだいぶ小さくなり計算処理も早くなりました。
修正したメソッドも置いておきます。

まあ普通に気付けよってところですねw
XAML
<Window x:Class="HTMLTableMaker.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="HTMLTableMaker" Height="350" Width="525">

<DockPanel>
<StatusBar DockPanel
<StatusBarItem>
<Label Content="進捗度"/>
</StatusBarItem>
<StatusBarItem>
<ProgressBar Name="progress" Height="18" Width="200" />
</StatusBarItem>
<StatusBarItem>
<Label Name="pLabel" Content="0%" />
</StatusBarItem>
</StatusBar>
<Grid>
<Button Content="画像取得" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<Image Height="230" HorizontalAlignment="Left" Margin="12,41,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="228" />
<Button Content="Table生成" Height="23" HorizontalAlignment="Left" Margin="246,12,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
<TextBox Height="230" HorizontalAlignment="Left" Margin="246,41,0,0" Name="textBox1" VerticalAlignment="Top" Width="245" VerticalScrollBarVisibility="Auto" TextWrapping="WrapWithOverflow" AcceptsReturn="True" />
</Grid>
</DockPanel>
</Window>


C#コード
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using System.Windows.Threading;
using System.Threading;
using System.ComponentModel;

namespace HTMLTableMaker {
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window {

private BitmapSource bmi1;
private BitmapDecoder dec;
private WriteableBitmap bmi2;
private int count;
private DispatcherTimer dt;
private byte[] pxdata;
private String tabletext;

public MainWindow() {
InitializeComponent();
}

private void button1_Click(object sender, RoutedEventArgs e) {
OpenFileDialog ofg = new OpenFileDialog();
ofg.DefaultExt = ".jpg";
ofg.Filter = "Image Files (*.jpg,*.gif,*.png)|*.jpg;*.gif;*.png";

// Show open file dialog box
Nullable<bool> result = ofg.ShowDialog();

// Process open file dialog box results
if (result == true) {
// Open document
string filename = ofg.FileName;
try {
dec = BitmapDecoder.Create(new Uri(filename), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
bmi1 = dec.Frames[0];

bmi2 = new WriteableBitmap(bmi1.Clone());
image1.Source = bmi2;



} catch (Exception err) {
MessageBox.Show(err.Message);
}
}
}

private void button2_Click(object sender, RoutedEventArgs e) {

//B,G,R,Aの順番に格納される。
int x = bmi1.PixelWidth;
int y = bmi1.PixelHeight;

pxdata = new byte[bmi1.PixelHeight * bmi1.PixelWidth * 4];
int stride = bmi1.PixelWidth * ((bmi1.Format.BitsPerPixel + 7) / 8);
bmi1.CopyPixels(pxdata, stride, 0);

//プログレスバーの設定
count = 0;
progress.Maximum = x * y;
dt = new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 0, 0, 200);
dt.Tick += showProgress;
dt.Start();

BackgroundWorker bw = new BackgroundWorker();
//bw.DoWork += makeTable;
bw.DoWork += makeCanvasHTML5;
bw.RunWorkerCompleted += runCompleted;
bw.RunWorkerAsync();

}

private void runCompleted(object sender, RunWorkerCompletedEventArgs e) {
textBox1.Text = tabletext;
}

private void makeCanvasHTML5(object sender, DoWorkEventArgs e) {
//B,G,R,Aの順番に格納される。
int x = bmi1.PixelWidth;
int y = bmi1.PixelHeight;
int i, j;

tabletext = "<!DOCTYPE html>\n";
tabletext += "<html><head>\n";
tabletext += "<meta charset=\"UTF-8\">\n";
tabletext += "<title>HTML5で画像を描画(嘘)</title>\n";
tabletext += "<style>\n";
tabletext+="body{\nbackground-color:#c0c0c0;\n}\n";
tabletext += "#cvs{\nbackground-color:#ffffff;\nborder:#000000 2px solid;\n}\n";
tabletext += "</style>\n";
tabletext += "<script>\n";
tabletext += "function draw(){\n";
tabletext += "var gazou=document.getElementById(\"cvs\").getContext(\"2d\");\n";


for (i = 0; i < y; i++) {
for (j = 0; j < x; j++) {
int red = pxdata[4 * (i * bmi1.PixelWidth + j) + 2];
int green = pxdata[4 * (i * bmi1.PixelWidth + j) + 1];
int blue = pxdata[4 * (i * bmi1.PixelWidth + j) + 0];
int alpha = pxdata[4 * (i * bmi1.PixelWidth + j) + 3];
string str = "";
str += red.ToString("x2");
str += green.ToString("x2");
str += blue.ToString("x2");


tabletext += "gazou.beginPath();\n";
tabletext += "gazou.moveTo(" + (100 + j) + ", " + (100 + i) + ");\n";
tabletext += "gazou.lineTo(" + (100 + j) + ", " + (101 + i) + ");\n";
tabletext += "gazou.lineTo(" + (101 + j) + ", " + (101 + i) + ");\n";
tabletext += "gazou.lineTo(" + (101 + j) + ", " + (100 + i) + ");\n";
tabletext += "gazou.closePath();\n";
tabletext += "gazou.fillStyle = \"#"+str+"\";\n";
tabletext += "gazou.fill();\n";


count++;
}
}
tabletext += "}\n";
tabletext += "</script>\n";
tabletext += "</head>\n";
tabletext += "<body>\n";
tabletext += "<h1>canvasでの画像表示(嘘)</h1>\n";
tabletext += "<p>下の矩形に画像を表示します</p>\n";
tabletext += "<canvas id=\"cvs\" width=\"" + (x + 200) + "\" height=\"" + (y + 200) +
"\"></canvas>\n";
tabletext += "<br>\n";
tabletext += "<form name=\"frm_1\">\n";
tabletext += "<input type=\"button\" value=\"画像を描画\" onclick=\"draw()\">\n";
tabletext += "</form>\n";
tabletext += "</body></html>";


}

private void makeTable(object sender, DoWorkEventArgs e) {
//B,G,R,Aの順番に格納される。
int x = bmi1.PixelWidth;
int y = bmi1.PixelHeight;
int i, j;

tabletext = "<table cellpadding=0 cellspacing=0 height=" + y +
" width=" + x + " style=\"height:" + y + "px;width:" + x + "px\">\n";
tabletext += "<tr height=0>";
for (j = 0; j < x; j++) {
tabletext += "<td width=1 />";
}
tabletext += "</tr>\n";

for (i = 0; i < y; i++) {
tabletext += "<tr height=1>";
for (j = 0; j < x; j++) {
int red = pxdata[4 * (i * bmi1.PixelWidth + j) + 2];
int green = pxdata[4 * (i * bmi1.PixelWidth + j) + 1];
int blue = pxdata[4 * (i * bmi1.PixelWidth + j) + 0];
int alpha = pxdata[4 * (i * bmi1.PixelWidth + j) + 3];
string str = "";
str += red.ToString("x2");
str += green.ToString("x2");
str += blue.ToString("x2");

tabletext += "<td bgcolor=\"#" + str + "\" />";
count++;
}
tabletext += "</tr>\n";
}
tabletext += "</table>";


}

private void showProgress(object sender,EventArgs e) {
progress.Value = count;
pLabel.Content = count * 100 / progress.Maximum + "%";
if (count >= progress.Maximum) {
dt.Stop();
}
}
}
}


メソッド修正
        private void makeCanvasHTML5(object sender, DoWorkEventArgs e) {
//B,G,R,Aの順番に格納される。
int x = bmi1.PixelWidth;
int y = bmi1.PixelHeight;
int i, j;

tabletext = "<!DOCTYPE html>\n";
tabletext += "<html><head>\n";
tabletext += "<meta charset=\"UTF-8\">\n";
tabletext += "<title>HTML5で画像を描画(嘘)</title>\n";
tabletext += "<style>\n";
tabletext += "body{\nbackground-color:#c0c0c0;\n}\n";
tabletext += "#cvs{\nbackground-color:#ffffff;\nborder:#000000 2px solid;\n}\n";
tabletext += "</style>\n";
tabletext += "<script>\n";
tabletext += "function draw(){\n";
tabletext += "var gazou=document.getElementById(\"cvs\").getContext(\"2d\");\n";

tabletext += "var width=" + x + ";\n";
tabletext += "var height=" + y + ";\n";

tabletext += "var rgb = [";

for (i = 0; i < x; i++) {
for (j = 0; j < y; j++) {
int red = pxdata[4 * (j * x + i) + 2];
int green = pxdata[4 * (j * x + i) + 1];
int blue = pxdata[4 * (j * x + i) + 0];
int alpha = pxdata[4 * (j * x + i) + 3];
string str = "";
str += red.ToString("x2");
str += green.ToString("x2");
str += blue.ToString("x2");

if (i == x - 1 && j == y - 1) {
tabletext += "\"" + str + "\"];\n";
} else {
tabletext += "\"" + str + "\",";
}


count++;
}
}

tabletext += "for(var i = 0; i < width; i++){\n";
tabletext += "for(var j = 0; j < height; j++){\n";

tabletext += "gazou.beginPath();\n";
tabletext += "gazou.moveTo(100+i,100+j);\n";
tabletext += "gazou.lineTo(100+i,101+j);\n";
tabletext += "gazou.lineTo(101+i,101+j);\n";
tabletext += "gazou.lineTo(101+i,100+j);\n";
tabletext += "gazou.closePath();\n";
tabletext += "var str = \"#\" + rgb[i*height+j];\n";
tabletext += "gazou.fillStyle = str;\n";
tabletext += "gazou.fill();\n";

tabletext += "}\n";
tabletext += "}\n";


tabletext += "}\n";
tabletext += "</script>\n";
tabletext += "</head>\n";
tabletext += "<body>\n";
tabletext += "<h1>canvasでの画像表示(嘘)</h1>\n";
tabletext += "<p>下の矩形に画像を表示します</p>\n";
tabletext += "<canvas id=\"cvs\" width=\"" + (x + 200) + "\" height=\"" + (y + 200) +
"\"></canvas>\n";
tabletext += "<br>\n";
tabletext += "<form name=\"frm_1\">\n";
tabletext += "<input type=\"button\" value=\"画像を描画\" onclick=\"draw()\">\n";
tabletext += "</form>\n";
tabletext += "</body></html>";


}
スポンサーサイト

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://kagenyan.blog69.fc2.com/tb.php/142-5af7f77e
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。