• ベストアンサー

GDI+を使ったビット数とDPIの扱い

http://okwave.jp/qa/q8858627.html このページでVBAのGDI+を使った8bitや24bitの画像の取扱方にについて教えていただきました。 追加の質問なのですが 画像を読み込んで画像のビット数を調べるにはどうしたら良いですか? 8bitなのか24bitなのか? それと読み込んだ画像のdpiを取得する方法および dpiを設定して画像を保存するにはどうしたら良いですか? 検索して調べてみましたが見つかりませんでしたので ご助言いただけないでしょうか?  

質問者が選んだベストアンサー

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

#1です。 下記をお試し下さい。 Public Declare Function GdipGetImageHorizontalResolution Lib "gdiplus" (ByVal Image As Long, resolution As Single) As Long Public Declare Function GdipGetImageVerticalResolution Lib "gdiplus" (ByVal Image As Long, resolution As Single) As Long こちらは簡単ではなさそうな気がします。当方の良く分かっていないGDI+のGraphicsがからんできそうな気配が... Public Declare Function GdipBitmapSetResolution Lib "gdiplus" (ByVal bitmap As Long, ByVal xdpi As Single, ByVal ydpi As Single) As Long 以上、ご参考まで。

その他の回答 (3)

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.4

#3の構造体、API宣言等です。 Public Type GdiplusStartupInput GdiplusVersion As Long DebugEventCallback As Long SuppressBackgroundThread As Long SuppressExternalCodecs As Long End Type Public Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type Public Type EncoderParameter GUID As GUID NumberOfValues As Long Type As Long Value As Long End Type Public Type EncoderParameters Count As Long Parameter(15) As EncoderParameter End Type Public Const CLSID_JPEG As String = "{557CF401-1A04-11D3-9A73-0000F81EF32E}" Public Const CLSID_QUALITY As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}" Public Declare Function GdipCreateBitmapFromFile Lib "gdiplus" _ (FileName As Any, bitmap As Long) As Long Public Declare Function GdipCreateBitmapFromGraphics Lib "gdiplus" _ (ByVal Width As Long, ByVal Height As Long, _ ByVal Target As Long, bitmap As Long) As Long Public Declare Function GdipDeleteGraphics Lib "gdiplus" _ (ByVal graphics As Long) As Long Public Declare Function GdipDisposeImage Lib "gdiplus" _ (ByVal image As Long) As Long Public Declare Function GdipDrawImageRectI Lib "gdiplus" _ (ByVal graphics As Long, ByVal image As Long, _ ByVal x As Long, ByVal y As Long, _ ByVal Width As Long, ByVal Height As Long) As Long Public Declare Function GdipGetImageGraphicsContext Lib "gdiplus" _ (ByVal image As Long, graphics As Long) As Long Public Declare Function GdipGetImageHeight Lib "gdiplus" _ (ByVal image As Long, Height As Long) As Long Public Declare Function GdipGetImageWidth Lib "gdiplus" _ (ByVal image As Long, Width As Long) As Long Public Declare Function GdipSaveImageToFile Lib "gdiplus" ( _ ByVal image As Long, _ ByVal FileName As Long, _ ByRef clsidEncoder As GUID, _ ByVal encoderParams As Any) As Long Public Declare Sub GdiplusShutdown Lib "gdiplus" _ (ByVal token As Long) Public Declare Function GdiplusStartup Lib "gdiplus" _ (token As Long, pInput As GdiplusStartupInput, _ pOutput As Any) As Long Public Declare Function GdipBitmapSetResolution Lib "gdiplus" (ByVal bitmap As Long, ByVal xdpi As Single, ByVal ydpi As Single) As Long Public Declare Function CLSIDFromString Lib "ole32.dll" ( _ ByVal lpszCLSID As Long, _ ByRef pCLSID As GUID) As Long

myumyu1234
質問者

お礼

何から何までありがとうございます。  

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

mitarashiです。昔某所で教わった画像リサイズのコードを改変すると、一応dpiの変更が出来た様です。但し、Indexed画像はGraphicsが生成出来ないそうで対象になりません。 構造体、APIのDeclare等は別途投稿します。 Sub changeDpi() Dim IID_IDispatch As GUID Dim udtInput As GdiplusStartupInput Dim lngToken As Long, lngStatus As Long Dim pGraphics As Long Dim pSrcBmp As Long, pDstBmp As Long Dim lngWidth As Long, lngHeight As Long Dim EncodParameters As EncoderParameters Dim srcPath As String, dstPath As String Const jpegQuality As Long = 90 Const myDpi As Long = 300 srcPath = GetDesktopPath & "\sample1.jpg" dstPath = GetDesktopPath & "\sample2.jpg" ' 初期化 udtInput.GdiplusVersion = 1 If GdiplusStartup(lngToken, udtInput, ByVal 0&) <> 0 Then Exit Sub End If ' 画像の読みこみ If GdipCreateBitmapFromFile(ByVal StrPtr(srcPath), pSrcBmp) <> 0 Then GdiplusShutdown lngToken Exit Sub End If ' 元画像サイズの取得 GdipGetImageWidth pSrcBmp, lngWidth GdipGetImageHeight pSrcBmp, lngHeight If GdipGetImageGraphicsContext(pSrcBmp, pGraphics) = 0 Then ' コピー先Bitmap作成 lngStatus = GdipCreateBitmapFromGraphics( _ lngWidth, lngHeight, pGraphics, pDstBmp) 'dpiの指定 lngStatus = GdipBitmapSetResolution(pDstBmp, myDpi, myDpi) GdipDeleteGraphics pGraphics If lngStatus = 0 Then ' コピー用Graphics作成 If GdipGetImageGraphicsContext(pDstBmp, pGraphics) = 0 Then ' イメージのコピー GdipDrawImageRectI pGraphics, pSrcBmp, 0, 0, lngWidth, lngHeight GdipDeleteGraphics pGraphics ' エンコーダパラメータ設定 EncodParameters.Count = 1 With EncodParameters.Parameter(0) .GUID = ConvCLSID(CLSID_QUALITY) .NumberOfValues = 1 ' 4=EncoderParameterValueTypeLong .Type = 4 ' 圧縮品質 .Value = VarPtr(jpegQuality) End With ' JPG変換で保存 Call GdipSaveImageToFile(pDstBmp, StrPtr(dstPath), ConvCLSID(CLSID_JPEG), VarPtr(EncodParameters)) End If GdipDisposeImage pDstBmp End If End If GdipDisposeImage pSrcBmp GdiplusShutdown lngToken End Sub Private Function ConvCLSID(ByVal sGuid As String) As GUID CLSIDFromString StrPtr(sGuid), ConvCLSID End Function GraphicsというのはGDI+のキャンバスの様な物で、拡大縮小回転、描画といった操作はこの上で行う必要があるそうです。.NETの説明ですが、ご参考まで。 http://msdn.microsoft.com/ja-jp/library/5y289054%28v=vs.110%29.aspx

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.1

こちらでそれらしい関数を探してみて下さい。 https://github.com/javiercrowsoft/cairo-vb6/blob/master/CSChart/GDI%2B/Codigo2/GpGDIPlus/Module/modGDIPlus.bas 本家のこちらもご参考になるでしょう。 http://msdn.microsoft.com/en-us/library/ms533969(v=vs.85).aspx 色深度については、GdipGetImagePixelFormatを検索してみつかった下記コードで、8bitIndexedのBMPについては、"&H" & Hex(Depth) -> PixelFormat8bppIndexed = &H30803が得られました。透明が入っていると所期の結果にならないとあり、返事ももらえていない様ですが... http://www.vbforums.com/showthread.php?718163-GDI-GdipGetImagePixelFormat-%28untrusted%29 以上、とりあえずご参考まで。

myumyu1234
質問者

お礼

毎度毎度、ご回答ありがとうございます。 GdipGetImagePixelFormatの方はうまくいきました。 dpiの取得の方なのですが Private Declare Function GdipGetImagePixelFormat Lib "gdiplus.dll" ( _ ByVal pImage As Long, _ ByRef pFormat As Long) As Long を宣言して Call GdipGetDpiX(hBmp, dpi_x) で取得を試みたのですが dpi_xの値は0になってしまいます。 どうすれば良いでしょうか?

myumyu1234
質問者

補足

間違いました 宣言する関数は Private Declare Function GdipGetDpiX Lib "gdiplus" (ByVal graphics As Long, dpi As Single) As Long です。 これでうまくいかないのですがなぜでしょうか?  

関連するQ&A