ASP.netでの画像回転について


himizu  2013-03-13 20:52:43  No: 148106  IP: [192.*.*.*]

画像を表示している画面に画像回転ボタンを配置しています。

画像は、サーバー側に存在しております。
現状は回転ボタン処理を押下すると回転した画像を
OutputStreamでクライアントへ返してます。
処理的には以下の様にしております。

Dim url As String = ImageURL
Dim wc As New WebClient
Dim stream As Stream = wc.OpenRead(Server.MapPath(url))
Dim img As Image = New Bitmap(stream)
'//回転指定
img.RotateFlip(RotateFlipType.Rotate90FlipXY)
img.Save(Response.OutputStream, ImageFormat.Jpeg)
img.Dispose()


ただ、上記だと別ページに回転後の画像を表示する動作となってしまいます。
実現したい内容としては、同一ページに回転後の画像を表示できる方法を模索しております。
サーバー側の画像を加工保存しなくてもクライアント側にて回転させることができればいいです。
何かご助言ありましたら宜しくお願いします。

編集 削除
魔界の仮面弁士  2013-03-14 15:29:54  No: 148107  IP: [192.*.*.*]

> 上記だと別ページに回転後の画像を表示する動作となってしまいます。
何故でしょう? サーバー側は画像を返すだけで、HTML ページの生成に
携わっているわけではないのなら、クライアント側のページまで
遷移させる必要は無いと思うのですが…。

処理の概念的には、元画面側に
  <img src="foo.aspx?rotate=90&amp;url=image/logo.png"
       width="100" height="100" alt="sample" id="img1" />
のようなタグを配置しておき、上記の src を JavaScript から
変更させるような仕組みを連想したのですが、そうではないのでしょうか。


> サーバー側の画像を加工保存しなくてもクライアント側にて回転させることができればいいです。
IE限定で良いなら、
 img1 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); }
のスタイルシートを、スクリプトで切り替える手があります。
http://msdn.microsoft.com/en-us/library/ms532918.aspx

HTML5 対応のブラウザなら、<canvas> を rotate して drawImage とか。
https://sites.google.com/site/westinthefareast/home/html5/imagerotate

それ以外だと、CSS3 の transform とか、Siverlight で RotateTransform とか。

それらよりも古い環境、たとえ IE4 あたりが相手となると、あとは
DirectAnimation (clsid:b6ffc24c-7e13-11d0-9b47-00c04fc2f51d) の
Transform メソッドとか。

編集 削除
himizu  2013-03-18 16:02:27  No: 148108  IP: [192.*.*.*]

>魔界の仮面弁士さま

ご助言有難う御座います。


>クライアント側のページまで遷移させる必要は無いと思うのですが…。
ご指摘の通りで、サーバーに保存されている画像は加工しませんので
クライアント側のみで画像回転できれば、問題ありません。
ただいろいろ調べたてみて画像回転する手法において、上記の手法を参考にしてしまいました。


実際やりたいこととしては、IE6以上にて、画像表示している画面にて
回転ボタンを押したら、クライアント側にて画像が回転される(90度)ようにしたいです。


>IE限定で良いなら、
IE限定となると少し厳しいです

>HTML5 対応のブラウザなら、
調べるとIE6はHTML5非対応とありましたので別の方法かなと思っております。

>それ以外だと、CSS3 の transform とか、Siverlight で RotateTransform とか
こちらもIE6では非対応の様で、何か良い方法はないでしょうか?

編集 削除
魔界の仮面弁士  2013-03-19 22:23:02  No: 148109  IP: [192.*.*.*]

>>> 上記だと別ページに回転後の画像を表示する動作となってしまいます。
>> クライアント側のページまで遷移させる必要は無いと思うのですが…。
> ご指摘の通りで、サーバーに保存されている画像は加工しませんので

先に提示されたコードは、サーバー側が「90度回転した画像」を返す実装ですよね。

『別ページに回転後の画像を表示する動作』の部分を修正して、
『同じページに回転後の画像を表示する動作』にしてやれば、
最初のコードをそのまま使うこともできるはずです。

これならば、大抵のブラウザで利用可能かと思います。画像処理を
サーバー側で実施するため、その分の追加アクセスは発生しますが…。


> クライアント側のみで画像回転できれば、問題ありません。
その場合ブラウザ側での対処が必要となりますが、どのバージョンのブラウザでも
通用するような万能な方法は無いでしょう。

IE5.5〜IE6 で回転させるなら、先に紹介したように
filter:progid:DXImageTransform.Microsoft.BasicImage を
用いるのが常套で、それが駄目なら Flash 頼みになるかと思います。
(IE8 以降 なら -ms-filter でもいけるかも)

他のブラウザーの場合には、SafariとGoogle Chrome では -webkit-transform の
rotate、Firefoxでは -moz-transform の rotate で回転できます。この手法では、
IE 用の -ms-transform の rotate も使えますが、これは IE9 以降が必要ですね。


> 実際やりたいこととしては、IE6以上にて、画像表示している画面にて
ここでは「やりたいこと」として「IE6以上」と書かれていますが、その一方で、
> IE限定となると少し厳しいです
とも書かれており、質問内容に一貫性が無いように思えます。

クライアント側のみで対処させるなら、どのバージョンのブラウザを
サポートするのか、実行環境を絞り込んでおきましょう。

その上で、先に回答した方法などを用いて、ユーザーエージェント判定を行ったり
ie の条件付きコメントを使ったり、あるいはベンダー固有cssの列挙によって
クロスブラウザーとなるよう、作りこんでいってみてください。

http://d.hatena.ne.jp/uupaa/20101029/1288292380
http://www.zachstronaut.com/posts/2009/02/17/animate-css-transforms-firefox-webkit.html



>> それ以外だと、CSS3 の transform とか、Siverlight で RotateTransform とか
> こちらもIE6では非対応の様で、何か良い方法はないでしょうか?
Siverlight 1〜Siverlight 4 までは IE6 に対応しています。
Siverlight 4、5 は IE7 以降ですね。
http://msdn.microsoft.com/ja-jp/silverlight/bb187452.aspx

なお、Siverlight については私の専門外です。(^^;

編集 削除
himizu  2013-03-20 15:35:50  No: 148110  IP: [192.*.*.*]

>魔界の仮面弁士さま

有難うございます。

>とも書かれており、質問内容に一貫性が無いように思えます。
言葉足らずで申し訳ありません。
クライアント側の実行環境は、メインで使用されているのが
IE6で、異なるブラウザを使用しているクライアントもいる状況なので
先に回答したような一貫性のない記述になってしまいました。。
IEにおいては、バージョン6以上で動作でき、他のブラウザでも動作可能な
状況にしておきたいということになります。


>『別ページに回転後の画像を表示する動作』の部分を修正して、
>『同じページに回転後の画像を表示する動作』にしてやれば、
>最初のコードをそのまま使うこともできるはずです。

まさにその通りでして、最初同じページに回転後の画像を表示しようと
トライしたのですが、方法が分からず断念してしまいました。。。
私としては、この方法を取りたいと考えておりましたが
現状実装方法が分からず、クラインとでのスクリプトで対応するしかないのかな
と思っておりました。
魔界の仮面弁士さまのおっしゃるとおりの方法にて
対応可能であるのならご助言お願いしたいです。

現状は、以下のように処理しております。
Formには、asp:Buttonコントロール二つ(左右90度)とasp:Image(ID:Image1)コントロールを配置しています。

'//************************************************************************************************
'//画面ロード
'//************************************************************************************************
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    '//画像表示
    Dim url As String = "サーバー上の画像パス"
    Dim img As Image = Image.FromFile(Server.MapPath(url))
    Image1.Height = img.Height
    Image1.Width = img.Width
    Image1.ImageUrl = url

End Sub


'//************************************************************************************************
'//左90度回転ボタンクリック
'//************************************************************************************************
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click

    Dim url As String = "サーバー上の画像パス"
    Dim wc As New WebClient
    Dim stream As Stream = wc.OpenRead(Server.MapPath(url))
    Dim img As Image = New Bitmap(stream)
    '//回転指定
    img.RotateFlip(RotateFlipType.Rotate90FlipXY)
    img.Save(Response.OutputStream, ImageFormat.Jpeg)
    img.Dispose()
End Sub

編集 削除
himizu  2013-03-21 16:52:49  No: 148111  IP: [192.*.*.*]

追記致します。

現状、回転後の画像を以下にてページに返してているので
元の画像表示画面のimgコントロール部分にこのデータを設定するのは
無理なのではと認識しております。
Dim stream As Stream = wc.OpenRead(Server.MapPath(url))
img.Save(Response.OutputStream, ImageFormat.Jpeg)

そこでもとのページのimgコントロール部分にサーバー側で
回転した画像を表示するには、サーバー側に回転後画像として保存しそのデータのURLを
設定するしか方法はないのでしょうか。
できれば、サーバーに回転後の画像を保存することは避けたいのですが
サーバー側で加工した画像を表示する場合は上記方法しかないのでしょうか。

上記方法をとってしまうと、回転後の画像の削除や、複数クライアント操作競合など
考慮しなければならないことが増えてしまうので
やはりクライアント側でスクリプト等にて画像を回転させるのが良法なのでしょうか。。

編集 削除
魔界の仮面弁士  2013-03-21 19:42:44  No: 148112  IP: [192.*.*.*]

>> 処理の概念的には、元画面側に
>>   <img src="foo.aspx?rotate=90&amp;url=image/logo.png"
>>        width="100" height="100" alt="sample" id="img1" />
>> のようなタグを配置しておき、上記の src を JavaScript から
>> 変更させるような仕組みを連想したのですが、そうではないのでしょうか。

上記の場合、画像を返すための foo.aspx は必要ですが、
クライアント側は、そもそも ASP.NET である必要すらありません。
JavaScript 付の sample.HTML があれば充分です。
(もちろん、PostBack も不要です)

> サーバー側に回転後画像として保存し

ファイルに書き込むのではなく、単に応答ストリームに
書き込むだけですよね。サーバー側でファイルとして
保存しておきたければそれでも良いですが、必ずしも
保存する必要は無いかと思います。


> やはりクライアント側でスクリプト等にて画像を回転させるのが良法なのでしょうか。。
パフォーマンスは断然良くなりますが、ブラウザーによって
回転処理のための記述が異なるため、サポートするブラウザの数だけ
テストと開発工数は増大していきます。
古いブラウザーも対象とするのであれば尚のこと。


> IEにおいては、バージョン6以上で動作でき、
単純に IE という括りだけでみると、こういうバージョンもあったりします。
http://msdn.microsoft.com/ja-jp/library/ie/jj883727.aspx
http://msdn.microsoft.com/ja-jp/library/ff462082.aspx

これらを抜きにしても、「IE6 以上」という括りにしてしまうと、
将来の IE11 以降のすべてのバージョンへの対応を保証することに
なるのでご注意下さい。(将来に渡って保証する予定なら別ですが…)

> 他のブラウザでも動作可能な状況にしておきたいということになります。
Mac、Linux、携帯電話、タブレット、ゲーム機など、ブラウザを搭載する
デバイスは多岐にわたります。「他のブラウザ」も含め、どの製品の
どのバージョンをサポートするのか、明確に絞り込んでおきましょう。

自身で検証できないバージョンを動作保証することはできないはずですから、
確認のとれたブラウザのみが、サポートできる環境という事になりますよね。

IE10 にしても、キーボード無し・マウス無し・タッチのみな環境と、
キーボードあり・マウスあり・タッチ無し・ペン入力ありな環境と、
キーボードとマウスのみの環境では、作りが異なることがあります。

編集 削除
himizu  2013-03-22 12:45:32  No: 148113  IP: [192.*.*.*]

ご返信有難うございます。

>クライアント側は、そもそも ASP.NET である必要すらありません。
こちらは、システム的にマスターページを使用しており
通常のHtmlへの変更は少し厳しい状況です。。
(認識間違っておりましたらすみません)


>ファイルに書き込むのではなく、単に応答ストリームに
>書き込むだけですよね。サーバー側でファイルとして
>保存しておきたければそれでも良いですが、必ずしも
>保存する必要は無いかと思います。

ここについてご教示願えますでしょうか?
サーバーサイドにて応答ストリームに書き込んだデータを
元のページのasp:imageコントロールに表示させることは
不可能なのでしょうか。
これができれば一番いいのですが。。

編集 削除
魔界の仮面弁士  2013-03-22 15:09:38  No: 148114  IP: [192.*.*.*]

サンプルコードを掲載しておきます。
http://www.vb-user.net/junk/replySamples/2013.03.22.09.39/sample.html
http://www.vb-user.net/junk/replySamples/2013.03.22.09.39/Client.aspx

ASP.NET は専門外なので、ASP ライクなコードに
なってしまっていますが…一応、当方では動作しています。


> こちらは、システム的にマスターページを使用しており
マスターページという概念は聞いたことがあるのですが、
使ったことが無いため、残念ながら対応方法までは分かりませんし、
そもそも実現可能かどうかも保証できかねます。

ただ、サーバーコントロールをクライアントスクリプトから制御することは
可能だと聞いています。多分、下記あたりにヒントがあるのではないかと。
http://msdn.microsoft.com/ja-jp/library/dd410598%28vs.100%29.aspx
http://msdn.microsoft.com/ja-jp/library/50b7y38h%28vs.100%29.aspx

編集 削除