マルチtiffの作成方法が知りたい への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 るきお  (社会人) 投稿日時 2020/5/30 12:07:35
元となっている、マクロソフトのブログはVisual Basicの.NET 5における対応の拡大をアナウンスするポジティブな内容と、将来のバージョンでは言語機能の追加を行わないかもしれないというネガティブな内容を含む二面的なものです。
https://devblogs.microsoft.com/vbteam/visual-basic-support-planned-for-net-5-0/

今までのフレームワークの機能とVBの機能の進化を例をいくつか振り返ってみると、下記のようなものがありました。

1.フレームワークに動的言語ランタイム追加 → VBは機能追加なし。(C#はdynamic追加)
2.フレームワークでタプル追加 → VBでタプルを記述可能になった
3.フレームワークで非同期機能強化 → VBにAsync, Await 追加
4.フレームワークで新スコープ → VBでPrivate Protected追加
(※そうとう端折っています…)

このうち、1・2はVBの言語機能が強化されなかったとしてもフレームワークの機能を利用することはできます。
3・4はVBの言語機能の追加がなければ、フレームワークの新機能の利用が不可能(または著しく困難)です。

VBチームのブログが言っていることは、VBの言語自体の進化は今後行わないので、今後、3・4のようなケースでは、VBからは新しい機能が利用できなくなるかもしれないということことだと思います。

1・2のようなケースでもマイクロソフトが積極的に対応してくれないとプロジェクトやファイルのテンプレートが提供されなくなるとしたら不便です。

以上がひとまずアナウンスされていることだと理解しています。
https://devblogs.microsoft.com/vbteam/visual-basic-support-planned-for-net-5-0/

その理由として、ブログで挙げられていることは、VBでは(C#と違って)言語の安定性が重要であるということです。
.NET Coreの登場で.NETの世界がLinuxなど非Windowsの世界に大きく広がりました。これに追従するために現在の.NET Core版のVBでは 言語機能として存在していた MsgBox が削除されるなど言語としての安定性が損なわれています。

言語としての安定性を損なって、新しい世界についていくか、言語としての安定性を維持して古い世界(Windows)に残るかという選択でC#は新しい道をさらに進んでいくけど、VBは古い世界にとどまるということだと思います。

とは言え、これはオブラートに包んだきれいな文言であり、要するにVBを切り捨てるつもりだと解釈する人が多く、上記ブログにもさまざまなコメントが寄せられています。この解釈はニュアンスがネガティブですが、正しいかもしれません。今のところ私にはわかりません。

原文は「may not be supported in Visual Basic」であり、書いている人にもわからないのかもしれません。しかし、その可能性があるというアナウンスを素直に受け止め、それが実際のこととなったとしても困らないような行動をするチャンスをこのブログは与えてくれているのだと思います。

これまでのVBは敷居が低く・初心者が入りやすく、しかも新しい機能も使えるすばらしい言語でした。.NET Coreの新しい世界でも、この路線を継続して欲しいところですが、実際のところ具体的にどうなるのかはマイクロソフトが今後具体的に何をやって何をやらないかでわかっていくと思いますので、まずは見守っていきたいです。それがはっきりわかるのは 2021年予定の .NET 6 ですね。
投稿者 葉月  (社会人) 投稿日時 2020/5/30 09:57:56
>https://news.mynavi.jp/article/20200316-997140/
URLのサイトを見て驚きました。
C#により力を入れたいというマイクロソフトの方針でしょうか……
C#の需要を支えているのはVBメイン、C#をサブで使っているプログラマーのおかげでもある訳ですが。
VB外したらC#に移行する方は多いでしょうが、少なからずPythonや宿敵のJAVAに走る方も出てきそうです。

私はVBSやVB.NETのおかげで、プログラムの魅力がわかったので残念でなりません。
(C言語を学校で習いましたが、当時は敷居が高く畑違いの仕事を選ぶきっかけになりましたw)
VBは入門者から習得しやすいので、今後も開発を継続してほしいです。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/5/29 23:12:02
> dim 変換画像 as bitmap
> for i= 0 to 2
>  変換画像(i)=Directcast(画像(i),bitmap)
> next
>
> この方法で、エラーはなくなってTiffファイルができていました

そのコードだと、コンパイルエラーになるハズですよ。
「変換画像」が配列になっていませんから。

掲示板投稿時に括弧を書き忘れたのでしょうけれども、
配列の初期化処理が無いので、どちらにしてもエラーになりそう。



> 今でも、VB6.0で可能なものはVB6.0で作ってまして
一応、VB6 でも同じものを作ることはできますね。

「tiffImage.SaveAdd(baseImages(i), ep)」の部分は GdipSaveAdd API に、
「tiffImage.Save(fileName, ici, ep)」は、GdipSaveImageToFile API に置き換えられます。
https://docs.microsoft.com/en-us/windows/win32/gdiplus/-gdiplus-image-flat

ただそのためには、gdiplus.dll で提供される GDI+ Flat API を Declare 宣言する必要が
ありますので、コーディング量は増加してしまうことになります。



VB6 という言語は好きなのですが、自分はもう、スッカリ使わなくなってしまいました…。
VBA 7.x や VBScript 5.8 は、未だに使っているのですけれどね。

そもそも、.NET な方の VB も終焉を迎えつつあるのですよね。ちょっと寂しい。
https://news.mynavi.jp/article/20200316-997140/
投稿者 allgreen  (社会人) 投稿日時 2020/5/29 15:43:04
dim 画像(2) as image
dim 変換画像 as bitmap
for i= 0 to 2
  変換画像(i)=Directcast(画像(i),bitmap)
next
SaveMultiTiff("マルチ.tif", 変換画像, EncoderValue.CompressionLZW)

この方法で、エラーはなくなってTiffファイルができていました
ありがとうございました

現在、学校で使う「採点のアシスト」のプログラムを作ってまして
 ①マルチTiffのファイルを読み込む
 ②各設問の解答欄の枠を設定する
 ③同じ問題を、画面上に並べて、○なのか✕なのか部分点なのかを入力
 ④採点結果(点数)を、CSVファイルで出力
 ここまでができています

 今は、生徒の答案の画像データに、○✕部分点を書き込んだ画像データを作成して出力
 ここを作っています

今でも、VB6.0で可能なものはVB6.0で作ってまして
まだまだ、わからないことだらけです
これからも、よろしくお願いします
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/5/29 14:01:25
Image は抽象クラス、Bitmap はその派生クラスの一つですよね。

PictureBox の Image プロパティのデータ型は当然、
System.Drawing.Image 型であるわけですが、
実際にそこから得られるインスタンスは、どのデータ型になっていますか?

もしもそれが Bitmap 型であることが事前に分かっているのであれば、
「Dim 画像(2) As Image」ではなく「Dim 画像(2) As Bitmap」にしておき、
 DirectCast(PictureBox1.Image, Bitmap)
で本来のインスタンス型に戻してから取得すれば良いでしょう。

あるいは Image 型の配列が既にあるので、そこから
OfType 拡張メソッドや Array.ConvertAll 静的メソッドで
 Dim bmpImages() = 画像.OfType(Of Bitmap)().ToArray()
などと書くこともできるかと思います。


一方、PictureBox の内容が Bitmap ではなく Nothing や Metafile だとしたら、
まず Bitmap を用意することから始める必要があるでしょうね。
投稿者 allgreen  (社会人) 投稿日時 2020/5/29 11:15:32
そのぺーじは、見ているのですが

dim 画像(2) as image
画像(0)=picturebox1.image
画像(1)=picturebox2.image
画像(2)=picturebox3.image
SaveMultiTiff("マルチ.tif", 画像, "CompressionLZW")

これで実行すると、次のエラーになります
型 'System.Drawing.Image[]' のオブジェクトを型 'System.Drawing.Bitmap[]' にキャストできません。

投稿者 魔界の仮面弁士  (社会人) 投稿日時 2020/5/28 18:14:16
こちらは如何でしょう。
https://dobon.net/vb/dotnet/graphics/createmultitiff.html
投稿者 allgreen  (社会人) 投稿日時 2020/5/28 17:57:56
以前に質問した
Dim fd As New System.Drawing.Imaging.FrameDimension(マルチ画像.FrameDimensionsList(0))
画像ページ数 = マルチ画像.GetFrameCount(fd)
For i = 0 To 画像ページ数 - 1
    マルチ画像.SelectActiveFrame(fd, i)
    画像(i) = マルチ画像.Clone
Next
マルチ画像を画像(i)にぺーじごとに分離するものは、わかるようになりましたが
これの逆をやりたいのですが、方法がわかりません

やりたいのは
画像(0)、画像(1)、画像(2)を、ひとつのマルチ画像 のimage にして
tiffファイルにして保存をしたい

よろしくお願いします