グッドデザイン賞を受賞したウォーターサーバー >>

VB勉強しはじめて間もない者です。
配列には数値以外にも画像を格納する事ができるんですよね?
.gif画像を格納したいんですけど
数値を格納する時と違ってどのように書けばよいのでしょうか。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

'画像の格納というより


'System.Drawing.Bitmapクラスの格納だが
'(System.Drawing.ImageはMustInheritなクラスなので使えなかった(汗

'コード見てわからない場合は基礎からやり直したほうがいい。

'やっていることは配列で無い場合と変わらない。

Class Q3286833

Shared Sub Main()

Dim hoge As System.Drawing.Image()
hoge = New System.Drawing.Image() {New System.Drawing.Bitmap("C:\hoge.bmp"), New System.Drawing.Bitmap("C:\fuga.bmp")}



End Sub

End Class
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q画像ファイルを配列に格納する方法

http://oshiete.goo.ne.jp/qa/8852322.html


このページで、
配列から直接圧縮画像ファイルを出力する方法を教えていただきました。

次は圧縮画像ファイルから配列を読み取るプログラムを作りたいと考えています。

http://tanlab.blog.fc2.com/blog-entry-31.html

このページで画像ファイルをメモリに読み込む方法は書かれていて、
GdipCreateBitmapFromFile(ByVal StrPtr(file1), image)

で変数imageに読み込むことができます。

このimageを上記のページの変数pDstBitmapに回すことで、
読み込んだ画像を別の画像として出力できることがわかりました。

いまやりたいことは
変数imageあるいは変数pDstBitmapを配列に書き出すことなのですが
どうやれば良いでしょうか?

これらの変数はLongとして定義されていて、
型が配列ではないのですが
どのようにして扱えば良いのでしょうか?

一応、検索などして調べてみましたが
分かりませんでしたので教えてください。

http://oshiete.goo.ne.jp/qa/8852322.html


このページで、
配列から直接圧縮画像ファイルを出力する方法を教えていただきました。

次は圧縮画像ファイルから配列を読み取るプログラムを作りたいと考えています。

http://tanlab.blog.fc2.com/blog-entry-31.html

このページで画像ファイルをメモリに読み込む方法は書かれていて、
GdipCreateBitmapFromFile(ByVal StrPtr(file1), image)

で変数imageに読み込むことができます。

このimageを上記のページの変数pDstBitmapに回すことで、
読み込んだ画像を別...続きを読む

Aベストアンサー

http://oshiete.goo.ne.jp/qa/8852322.html
(http://oshiete.goo.ne.jp/qa/8852322.html)
で回答した者ですが、実はあの#1-2のコードには前半があって、ファイルからセル色に取り込んでいるのです。その部分を投稿しますので改造して下さい。

'(2) ファイルから画像を読み込みbitmapオブジェクトに変換する
If GdipCreateBitmapFromFile(ByVal StrPtr(strInName), pSrcBitmap) <> 0 Then
Exit Sub
End If
'(3) 読み込んだ画像のサイズを取得
'画素数は480x360程度でないと、書式が多すぎるというエラーが発生する
GdipGetImageWidth pSrcBitmap, lngWidth
GdipGetImageHeight pSrcBitmap, lngHeight

'(4) bitmapオブジェクトから1画素ずつ読み込んで、エクセルのセルのColorに設定
'GDI+から取得する色は透明度を含むARGBであるが、セルに設定する場合はBGRに変換する必要がある
Application.ScreenUpdating = False
For y = 0 To lngHeight - 1
For x = 0 To lngWidth - 1
'画素の色を取り出し、文字列に変換する
'ビットシフトは面倒そうなので、スピードは犠牲にして?文字列に変換して処理
GdipBitmapGetPixel pSrcBitmap, x, y, myARGB
strARGB = Hex(myARGB&)
With ActiveSheet
Range(.Cells(1, 1), .Cells(1, lngWidth)).ColumnWidth = 1.63
'ARGB->BGRに変換してセル色に変換
.Cells(y + 1, x + 1).Interior.color = RGB(CInt("&H" & Mid(strARGB, 3, 2)), CInt("&H" & Mid(strARGB, 5, 2)), CInt("&H" & Mid(strARGB, 7, 2)))
End With
Next x
Next y
Application.ScreenUpdating = True

>これらの変数はLongとして定義されていて、
>型が配列ではないのですが
>どのようにして扱えば良いのでしょうか?
ここでのimage、pDstBitmapは「ハンドル」と言われるものです。画像ファイルが読み込まれ、ビットマップオブジェクトが生成された時に、Windowsによってつけられた管理番号といった感じでしょうか。

ついでに、先のQAのARGBのオーバーフローについてですが、下記をご参照下さい。
http://support.microsoft.com/kb/189323/en-us
機械翻訳したページもありますが、よけいに分かり難いような...
http://support.microsoft.com/kb/189323

http://oshiete.goo.ne.jp/qa/8852322.html
(http://oshiete.goo.ne.jp/qa/8852322.html)
で回答した者ですが、実はあの#1-2のコードには前半があって、ファイルからセル色に取り込んでいるのです。その部分を投稿しますので改造して下さい。

'(2) ファイルから画像を読み込みbitmapオブジェクトに変換する
If GdipCreateBitmapFromFile(ByVal StrPtr(strInName), pSrcBitmap) <> 0 Then
Exit Sub
End If
'(3) 読み込んだ画像のサイズを取得
'画素数は480x360程度でないと、書式が多すぎるという...続きを読む

QVBAで配列からbmp画像を出力する方法

VBAで配列からbmp画像を出力する方法を教えてください。

例えば、
dim a(255,255)
で作成した二次元配列があり、それぞれの中に0~255の数値が格納されているとします。
この画像からグレースケールあるいは任意の配色で
256x256の解像度のbmp画像を出力するプログラムを
VBAで作りたいのですがどのようにすれば良いですか?


検索して調べたのですが、
http://www.vbalab.net/vbaqa/c-board.cgi?cmd=ntr;tree=54343;id=excel
http://akadamashy.blog68.fc2.com/blog-entry-915.html

のサイトにビットマップ画像を出力するための
プログラムが記載されていました。

しかしながら、どうしても配列からどうやって出力すれば良いか分かりません。

どなたか教えてください。

Aベストアンサー

> Sub sample()のところでp(500,500)の各配列に1か0を代入していますが、
> 0~255までのカラーを使いたい場合には、
> With RGBQUAD(0)で0~255まで全て定義する必要があるのでしょうか?

先の回答で示したページをよく読んでください。

> 変数kを0から7まで繰り返して、* 2 ^ (7 - k)を足していく操作が理解できないのですが
> 何をやっているのでしょうか?

実際にそのコードを実行し、数値を変更したりしてどのような画像が出来上がるのか試してみてください。理解しなくても関係の無いところだと思われますが。

> また、式の中で「\」マークが出てきますがこれは何を意味しているのでしょうか?

実際にご自身で計算式を作って試してみればわかることです。

以下の2行を実行してみてください。

Debug.Print 10 \ 3
Debug.Print 10 / 3

演算子
http://www.officepro.jp/excelvba/basic/index6.html

何もせず示したページもろくに読まないで質問ばかりするのはやめましょう。時間の無駄です。

> Sub sample()のところでp(500,500)の各配列に1か0を代入していますが、
> 0~255までのカラーを使いたい場合には、
> With RGBQUAD(0)で0~255まで全て定義する必要があるのでしょうか?

先の回答で示したページをよく読んでください。

> 変数kを0から7まで繰り返して、* 2 ^ (7 - k)を足していく操作が理解できないのですが
> 何をやっているのでしょうか?

実際にそのコードを実行し、数値を変更したりしてどのような画像が出来上がるのか試してみてください。理解しなくても関係の無いところだと思われま...続きを読む

Qファイルをメモリに出力する方法

ある配列をtiff画像ファイルとして出力したいのですが

配列を一度bmp画像ファイルとして出力して

http://oshiete.goo.ne.jp/qa/8809275.html

このページにある方法を使って、それをtiffファイルに変換して
残ったbmpファイルを削除するというプログラムを作りました。

この方法だと、HDDにアクセスする手順が多くなるため、ファイル数が多い時に時間がかかってしまいます。

bmpファイルをメモリにいったん保存しておいて、
それをtiffファイルに書き換えるようなプログラムを作るにはどうしたら良いですか?

あるいは配列から直接tiff画像ファイルを出力する方法があれば
教えてください。

Aベストアンサー

#1-3です。
型変換をVBAに頼り過ぎだと存じます。
真面目にやるべきでしょう。
簡単な例で試してみました。ご参考まで。

Sub test()
Dim myR As Byte, myG As Byte, myB As Byte
Dim myRGB As Long
myR = 255
myG = 255
myB = 255
myRGB = myR & myG & myB
Debug.Print Hex(myRGB) '->F36E2D7 白にならない
End Sub

Sub test2()
Dim myR As Byte, myG As Byte, myB As Byte
Dim myRGB As Long
myR = 255
myG = 255
myB = 255
myRGB = CLng("&H" & Hex(myR) & Hex(myG) & Hex(myB))
Debug.Print Hex(myRGB) '-> FFFFFF
End Sub

Sub test3()
Dim myR As Long, myG As Long, myB As Long 'Byte型だとmyR * &H10000のところでオーバーフロー
Dim myRGB As Long
myR = 255
myG = 255
myB = 255
myRGB = myR * &H10000 + myG * &H100 + myB
Debug.Print Hex(myRGB) '->FFFFFF
End Sub

#1-3です。
型変換をVBAに頼り過ぎだと存じます。
真面目にやるべきでしょう。
簡単な例で試してみました。ご参考まで。

Sub test()
Dim myR As Byte, myG As Byte, myB As Byte
Dim myRGB As Long
myR = 255
myG = 255
myB = 255
myRGB = myR & myG & myB
Debug.Print Hex(myRGB) '->F36E2D7 白にならない
End Sub

Sub test2()
Dim myR As Byte, myG As Byte, myB As Byte
Dim myRGB As Long
myR = 255
myG = 255
myB = 255
myRGB = CLng("&H" & Hex(myR) & Hex(myG) & Hex(myB))
...続きを読む

QVBでボタンを押すと画像をランダム表示させる

VisualBasic2005ExpressEditionで「ボタンを押すとピクチャーボックスに画像をランダムで表示」させたいんですが、どうやるかわかりません教えてください。何件か探しては見たんですが見つかりませんでした。もしかしてVBでは、そういったプログラムはできないんでしょうか?

Aベストアンサー

えっと、やり方は他にもあると思いますが、楽なやつで。

まず、それぞれの画像ファイルの名前を格納する配列を用意します。
Dim strPicture(10) As String
strPicture(0) = "pic1.jpg"
strPicture(1) = "pic2.jpg"
strPicture(2) = "pic3.jpg"



という風にやります。配列の数は表示させたい画像分だけ作ります。

次に、ランダムに表示させるということなので
乱数を発生させる必要がありますね。

' 0 以上 a 未満の乱数を取得する
Dim intResult As Integer = hRandom.Next(a)

とやります。 aはランダムに表示させたい画像の最大枚数-1ですね。
すると、intResultに、ランダムな数値が入ります。

そうしたら

PictureBox1.image = Image.FromFile(strPicture(intResult))

とします。

上記のコードを、ボタンをクリックしたときのイベントに追加すれば
OKです。

ただ、上記のように画像ファイル名のみだと
プログラムがあるフォルダ内に画像ファイルがないと読み込めないので
フルパスで書いた方がいいかもです。

strPicture(0) ="C:\~" という具合です。

えっと、やり方は他にもあると思いますが、楽なやつで。

まず、それぞれの画像ファイルの名前を格納する配列を用意します。
Dim strPicture(10) As String
strPicture(0) = "pic1.jpg"
strPicture(1) = "pic2.jpg"
strPicture(2) = "pic3.jpg"



という風にやります。配列の数は表示させたい画像分だけ作ります。

次に、ランダムに表示させるということなので
乱数を発生させる必要がありますね。

' 0 以上 a 未満の乱数を取得する
Dim intResult As Integer = hRandom.Next(a)

...続きを読む

Q複数の画像ファイルを挿入したい

工事の仕事をしています。
報告書をエクセルで書いて出すのですが、
現場の写真を大量に撮影して貼り付けなければなりません。

「挿入」→「ファイルから」で一枚一枚貼り付けているのですが手間でなりません。

デジカメで撮影した写真なのでファイル名は連番です。
一括でワークシートにズラッと並べて挿入することはできないのでしょうか?

週末1-200枚の写真を貼る為に残業するのは堪えます。
良い知恵をお貸し下さい。

Aベストアンサー

工事写真票の作成ですか?報告書の提出時期ですものね。(^^;)

工事写真ということで、次の点が重要になるかと思います。

1. 貼付けられる順番
  工事の様子を時間を追って撮影している場合、順番が重要です。
2. リサイズの問題
  工事写真は正確性が求められます。リサイズする場合、縦横比を固定すべきです。

1と2をクリアしつつ、貼付けを楽にするには、EXCELではマクロしか解決方法がありません。個人的にはVIXをお勧めしますが、一応EXCELでのマクロをアップします。貼付け後のサイズはセルの高さにあわせています。必要があれば、コードをカスタマイズして下さい。

ただ、他の方からもご指摘があるとおり、EXCELに200枚の画像は無茶ですね。複数のブックに切り分けましょう。

なお、マクロ[InsertPictures]は#2.papayukaさんのコードをかなり拝借しておりますし、配列のソートプログラムも以前どこかで教えて頂いたものです。クイックソートの方が早いのですが、長くなるので、バブルソートで済ませています。


以下コード。

Option Explicit
Sub InsertPictures()
  
  Dim fName As Variant
  Dim i As Long
  Dim Pict As Picture

  fName = Application.GetOpenFilename("JPGファイル, *.jpg", MultiSelect:=True)
  If IsArray(fName) Then
    Application.ScreenUpdating = False
    '配列に格納されたファイル名をソート
    BubbleSort fName, True
    For i = 1 To UBound(fName)
      Set Pict = ActiveSheet.Pictures.Insert(fName(i))
      With Pict
        .TopLeftCell = ActiveCell
        .ShapeRange.LockAspectRatio = msoTrue
        'どちらかをコメントアウト
        .ShapeRange.Height = ActiveCell.Height 'セルの高さリサイズ
        '.ShapeRange.Width = ActiveCell.Width 'セルの幅にリサイズ
        ActiveCell.Offset(0, 1) = fName(i) 'ファイル名書込み
      End With
      ActiveCell.Offset(2, 0).Activate
      Application.StatusBar = "処理中:" & i & "/" & UBound(fName) & "枚目"
    Next i
  End If
  With Application
    .StatusBar = False
    .ScreenUpdating = True
  End With
  Set Pict = Nothing
  MsgBox i & "枚の画像を挿入しました", vbInformation

End Sub

'値の入替え
Public Sub Swap(ByRef Dat1 As Variant, ByRef Dat2 As Variant)

  Dim varBuf As Variant
  varBuf = Dat1
  Dat1 = Dat2
  Dat2 = varBuf

End Sub

'配列のバブルソート
Public Sub BubbleSort(ByRef aryDat As Variant, _
  Optional ByVal SortAsc As Boolean = True)

  Dim i As Long
  Dim j As Long
  For i = LBound(aryDat) To UBound(aryDat) - 1
    For j = LBound(aryDat) To LBound(aryDat) + UBound(aryDat) - i - 1
      If aryDat(IIf(SortAsc, j, j + 1)) > aryDat(IIf(SortAsc, j + 1, j)) Then
        Call Swap(aryDat(j), aryDat(j + 1))
      End If
    Next j
  Next i

End Sub

工事写真票の作成ですか?報告書の提出時期ですものね。(^^;)

工事写真ということで、次の点が重要になるかと思います。

1. 貼付けられる順番
  工事の様子を時間を追って撮影している場合、順番が重要です。
2. リサイズの問題
  工事写真は正確性が求められます。リサイズする場合、縦横比を固定すべきです。

1と2をクリアしつつ、貼付けを楽にするには、EXCELではマクロしか解決方法がありません。個人的にはVIXをお勧めしますが、一応EXCELでのマクロをアップします。貼付け後のサイズはセ...続きを読む

QForm間の値の渡し方

1つのForm上のコマンドボタンで別のFormを表示、そこで変数に値を入れ、そのFormを閉じ、元のFormでその変数を使いたいのですが、どうもうまくいきません。
実施したやり方は、一方のFormの宣言領域で、”Public abc As String”を宣言、両方のFormの(変数に値を入れた方と変数を使う方の)プロシージャーの宣言では引数として(abc As String)と記述しました。
因みに、両プロシージャーともイベントプロシージャーです。何か基本的なことができていないのだとは思いますが、どなたか教えていただけませんか?よろしくお願いします。

Aベストアンサー

すでに何件か回答があがっていますので、少し変わった方法をご参考までに。

あまり使われませんが、Formにはtagというプロパティがあります。
これは「文字列形式であれば何でも格納できる」という、上手く使えば便利なプロパティです。

FormAからFormBを呼び出し、FormBで変更した値をFormA.tagにセットします。
ここでFormBをUnloadしてもFormA.tagの値は影響を受けないので自由に使えます。

複数の値を呼び出し元に戻してやる場合に、区切り文字(カンマなど)で連結した文字列をtagに格納し、呼び出し元で区切り文字でsplitして、複数の値を受け渡すという手法をよく使っています。

QVBAで画像を表示する方法

VBA初心者です。ExcelのVBAでプログラミングの練習をしています。
早速ですが質問させてください。
ユーザーフォーム上にコマンドボタンをクリックすることにより画像を表示させることはできるのですが、これをユーザーフォームを開いた瞬間に自動的に表示させる方法はないのでしょうか?

ちなみに現在は以下のようにしています。
Private Sub CommandButton1_Click()
Image1.Picture = LoadPicture(" ")
End Sub

インターネットで調べてみても見つからないので質問させてもらいました。分かりにくい説明でしたらすみません。

Aベストアンサー

UserFormのinitializeイベントかActivateイベントを使ってください。

Private Sub UserForm_Initialize()
 Image1.Picture = LoadPicture("C:\aaa.jpg")
End Sub

または、

Private Sub UserForm_Activate()
 Image1.Picture = LoadPicture("c:\aaa.jpg")
End Sub

QBitmap.GetPixelより高速なもの

いまVBでBitmap.GetPixelを使って、グレースケールの画像のRGBを取得しています。
まあグレースケールなんでRGB同じなのでとりあえずRの値を使うとして、
200*300の画像をFor文でBitmap.GetPixelを使うととてもじゃないぐらい遅いです。
ある程度調べると、LockBits()というものが見つかったのですが使い方がわかりません。 教えてください。

Aベストアンサー

補足されたコードをもう一度見直したほうがいいように思います

for LY ...
 for LX ...
  myBitmapの構築
  色情報の取得
  if 色判定 then
   Graphicsオブジェクトの生成
   描画
  end if
 next ' LX
next ' LY
といった構成になっています

2重ループの内側で myBitmapを毎回作成するのは無駄です
Graphicsオブジェクトの生成もループの内側でやった場合
連続して判定がTrueを返した場合毎回生成しなおします

変化しないものはループの外へ追い出して見ましょう

' Create a Bitmap object from an image file.
Dim myBitmap As New Bitmap(".\Test01.jpg")
Dim P As Graphics = PictureBox2.CreateGraphics

Dim LY As Long
' イメージ全体で行うなら 299をmyBitmap.Heightに
' 199を myBuitmp.Widthに変更したほうがいいでしょう
' 1行おきの処理なら Stepで調整する
For LY = 0 To 299 Step 2
  Dim LX As Long
  For LX = 0 To 199
    Try
      ' Get the color of a pixel within myBitmap.
      Dim pixelColor As Color = myBitmap.GetPixel(LX, LY)
      Red = pixelColor.R
      Label1.Text = "R" + Red
      If (Red > 40) Then
        P.FillRectangle(Brushes.White, LX, LY, 1, 1)
      End If
    Catch ex As Exception
    End Try
  Next
  ' 1行おきの処理をしたいのであれば For文にStepをつけましょう
  ' Forなど自動でカウントアップ(またはダウン)するものを
  ' コード内でいじってしまうのはあまり行儀がよくありません
  ' LY = LY + 1
Next

といった具合で 速度がずいぶん改善されるように思います

補足されたコードをもう一度見直したほうがいいように思います

for LY ...
 for LX ...
  myBitmapの構築
  色情報の取得
  if 色判定 then
   Graphicsオブジェクトの生成
   描画
  end if
 next ' LX
next ' LY
といった構成になっています

2重ループの内側で myBitmapを毎回作成するのは無駄です
Graphicsオブジェクトの生成もループの内側でやった場合
連続して判定がTrueを返した場合毎回生成しなおします

変化しないものはループの外へ追い出して見ましょう

' Cre...続きを読む

Qエクセル VBA ユーザーフォームを閉じる

ユーザーフォームを開く時は
UserForm1.Showですが
閉じる時は?
UserForm1.Close
だとコンパイルエラーになります。
End
にするしかないですか?

Aベストアンサー

Unload Me とか Unload UserForm1 でユーザーフォームを閉じることができます。

QVBAで配列引数を値渡しできない理由

Sub TestB(ByVal MyArray() As Integer)

のようにして、
配列引数をByValで渡そうとすると
エラーが出てしまいます。

http://vba.doorblog.jp/archives/51291826.html

このページにあるように
variantとして渡せば
エラーは出ないのですが
byrefとして扱われてしまいます。

なぜVBAでは配列を値渡しすることができないのでしょうか?
何が問題なのでしょうか?

Aベストアンサー

VBで配列を引数で渡す場合、先頭のアドレス(住所)を渡しています。
(C言語のポインター)
その為、サブルーチンの引数の型は、その「アドレスを表す変数」が値渡しか参照渡しかを表すことであって、配列の中身を値渡しか参照渡しかを指定している訳ではありません。
つまり、
Sub TestB(Byref MyArray() As Integer)
※MyArray変数がByref
Sub TestB(Byval MyArray As Variant)
※MyArray変数がByval

詳しくは、以下のサイトを参考にしてみてください。
https://msdn.microsoft.com/ja-jp/library/eek064h4.aspx


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング