質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

7169閲覧

PNG画像のピクセルサイズ取得について

ice930

総合スコア99

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/10/24 00:27

VBAで取得した画像サイズと、プロパティで確認したサイズ(ピクセル)が異なっており、原因を知りたく質問いたしました。
(※サイズとは、画像の縦横の長さのサイズです。)

このサイトを参考にPNG画像のサイズを取得しようと試みました。
(URL:https://excel-ubara.com/excelvba4/EXCEL263.html)
※「AddPictureしてから取得」の所です。

ほぼ同じコードですが以下にそのコードを記載します。

Sub sample2() Dim sp As Shape Dim pWidth As Long Dim pheight As Long Dim Path As String Path = "パスがここに入ります.png"'ここにPNG画像のパスが入ります。 If strFile = "False" Then Exit Sub End If Set sp = ActiveSheet.Shapes.AddPicture( _ Filename:=Path, _ LinkToFile:=False, _ SaveWithDocument:=True, _ Left:=0, _ Top:=0, _ Width:=0, _ Height:=0 _ ) With sp .LockAspectRatio = msoTrue .ScaleHeight 1, msoTrue .ScaleWidth 1, msoTrue pWidth = CLng(.Width * 4 / 3) pheight = CLng(.Height * 4 / 3) .Delete End With MsgBox "横:" & pWidth & vbLf & "縦:" & pheight End Sub

画像のプロパティで確認すると、155×211ですが、最後のMsgBoxでは「幅68 縦92」と表示されます。
比率を調べると、縦、横共に2.279・・・・ となるのですが関連性がわかりません。
プロパティで表示されているピクセルと、コード中でのピクセルは異なるものなのでしょうか。

サイトの上部には「ピクセル数を取得する方法について・・・」とあるので、「.Width * 4 / 3」でピクセル数になっているとは思うのですが。

原因、対策についてご助言いただければと思います。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

質問のコードで私の環境で試してみましたか、やはり実際のサイズとはズレがありました。
私の場合は、取得サイズに 1.5倍すると実際のサイズになりました。
環境によって変わるようですね。

参考にされたリンク先でも「GDIに依存する」という記述があります。
さらにAPIで取得する方法も紹介されてます。ただ、コードが間違っているのでエラーになりますので、動くように修正したもので試したら正確なサイズが取得できました。(64bitOfficeにも対応するように書き換えましたのでExcel2007以前ではエラーになります。)

vba

1Private Declare PtrSafe Function GdiplusStartup Lib "gdiplus" ( _ 2 ByRef token As LongPtr, _ 3 ByRef inputbuf As GdiplusStartupInput, _ 4 Optional ByVal outputbuf As LongPtr = 0) As Long 5Private Declare PtrSafe Sub GdiplusShutdown Lib "gdiplus" ( _ 6 ByVal token As LongPtr) 7Private Declare PtrSafe Function GdipLoadImageFromFile Lib "gdiplus" ( _ 8 ByVal FileName As LongPtr, _ 9 ByRef image As LongPtr) As Long 10Private Declare Function GdipGetImageDimension Lib "gdiplus" ( _ 11 ByVal image As LongPtr, _ 12 ByRef Width As Single, _ 13 ByRef Height As Single) As Long 14Private Type GdiplusStartupInput 15 GdiplusVersion As Long 16 DebugEventCallback As LongPtr 17 SuppressBackgroundThread As Long 18 SuppressExternalCodecs As Long 19End Type 20 21Function GetImgSize(ByVal sImageFilePath As String, _ 22 ByRef x As Single, _ 23 ByRef y As Single) As Boolean 24 Dim uGdiStartupInput As GdiplusStartupInput 25 Dim nGdiToken As Long 26 Dim nStatus As Long 27 Dim hImage As Long 28 GetImgSize = False 29 x = 0: y = 0 30 uGdiStartupInput.GdiplusVersion = 1 31 nStatus = GdiplusStartup(nGdiToken, uGdiStartupInput, 0&) 32 If nStatus = 0 Then 33 nStatus = GdipLoadImageFromFile(ByVal StrPtr(sImageFilePath), hImage) 34 If nStatus = 0 Then 35 nStatus = GdipGetImageDimension(hImage, x, y) 36 If nStatus = 0 Then 37 GetImgSize = True 38 End If 39 End If 40 Call GdiplusShutdown(nGdiToken) 41 End If 42End Function 43 44Sub sample1() 45 Dim path As String 46 path = "パスがここに入ります.png" 47 48 Dim x As Single, y As Single 49 50 If GetImgSize(path, x, y) Then 51 MsgBox "横:" & x & vbLf & "縦:" & y 52 Else 53 MsgBox "サイズ取得失敗" 54 End If 55End Sub

投稿2020/10/24 03:28

hatena19

総合スコア33620

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ice930

2020/10/24 13:55

ありがとうございます! APIさえ習得できれば「出来ること」の幅が広がりそうです! 今のところAPIの知識は有りませんが、今後APIを学習する際に参考にさせていただきます!
guest

0

他の方の回答にあるようにポイントからピクセルへの換算の問題なので、ディスプレイの拡大率に依存しますね。
具体的にはここです。たぶんあなたの環境では225%なのではないかと。
ディスプレイの拡大縮小
しばらく前までWindowsではディスプレイの拡大縮小は一般的ではなく、OS上での解像度は現実のディスプレイによらず96dpiに固定されていたので、1ポイント(=1/72インチ)は3/4ドット固定でした。それを前提に作られたプログラムなのだと思います。
拡大率をVBAから取得できれば解決するのですが、方法があるかちょっと分かりません。


なるほど、ポイント→ピクセル変換の問題を思わせる状況でしたが、100%であったとなると、hatena19さんの言うとおりそうではないのでしょうね。
私の回答は的外れだったようです。

投稿2020/10/24 08:09

編集2020/10/24 16:33
ikadzuchi

総合スコア3047

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ice930

2020/10/24 13:52

画像添付など、分かり易い回答ありがとうございます! 確認したところ、画像の比率は100%となっておりましたが、今後不具合等が起きた際は参考にさせていただきます!
guest

0

誤回答のため削除いたします。

> VBAで取得した画像サイズと、プロパティで確認したサイズ(ピクセル)が異なっており

~~とのことですが、下記サイトによるとLoadPicture()で取得したオブジェクトの幅・高さの単位はポイントのようです。なので数値が異なっているのではなく単位が異なっているのです。
~~

Excel VBAでJPG・GIF・PNGの画像ファイルから画像サイズを取得してみる

> 取得した幅と高さは単位がポイントなので、ピクセルに変換します。

投稿2020/10/24 01:17

編集2020/10/24 17:35
meg_

総合スコア10577

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hatena19

2020/10/24 08:18

LoadPicture() はPNGには対応していないので、質問のコードは別の方法を使ってます。 よって、ポイント→ピクセル変換の問題ではないです。
meg_

2020/10/24 17:34

> 「.Width * 4 / 3」でピクセル数になっているとは思う ここより”単位”の問題かと思ってしまいました。 > 155×211ですが、最後のMsgBoxでは「幅68 縦92」と表示 > 比率を調べると、縦、横共に2.279 こちらが質問の意図だったのですね。 VBAの知識もないのに間違った回答をしてしまい申し訳ありませんでした。
ice930

2020/10/25 00:36

とんでもございません。 Lordpictureも良く使用するので、参考になりました! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問