-
Feb 13th, 2018, 02:46 PM
#1
Thread Starter
Addicted Member
Get image size of IPicture with GDI routine
Hi all...
how do we get the image size (real one) of a IPicture with GDI call.
(let's suppose I don't want to use the IPicture.width for some IDE crash issue)
1. I Open GDI+
2. I load an Image with GDI+ in a IPicture Struct
3. I Close GDI+
somewhere elses in the program...
I need the size of the picture ?
I got a project I'll post here soon when I'm finish, it's a PNG ocx (not fancy like the AIC - Lavolpe)
wich I want to use for futur application I do because I'm using new way to "skin" that require transparency.
I wanted to go with PNG instead of using TransparentBlt wich would have required all my image to have the "same" transparency color.
My new ocx is using the alpha blend (per pixel) and background transparency all in one.
thank
-
Feb 13th, 2018, 02:52 PM
#2
Re: Get image size of IPicture with GDI routine
That may explain the problem. GDI+ image handle (hImage) is not a picture handle that can be used with GDI APIs or VB. I'm interested in how you created a valid IPicture from a GDI+ image handle.
-
Feb 13th, 2018, 03:10 PM
#3
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
sure, let me post the code... (give me a minute)
in the meanwhile, accessing the .width and .height of the IPicture only crash when you put your mouse cursor over it in debug mode.
and I answered my own question with your post from where I came here, that is with:
lngSrcWidth = ScaleX(pobjIPicture.Width, vbHimetric, vbPixels)
lngSrcHeight = ScaleY(pobjIPicture.Height, vbHimetric, vbPixels)
the nice part is that my "aic" (promise I won't call it that) take only a few line of code to read png and store it in the OCX
(so thanks for the solution you gave in the other thread)
I'm gonna get the routine and post it here for your evaluation.
-
Feb 13th, 2018, 03:24 PM
#4
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
why people doesn't put their credential in ZIP file with code it elude me...
so again... credit is due to the author, I borrowed a few routine from a project and I got the zip but not where I took it.
so if you recognize your work, plz tell me so I can FIX that and give you the credit. (post me the link where I took the zip, I'll recognize it)
I'm sorry again.
Lavolpe: I adapted some code to fit my idea and I can now use full transparency and alpha blending (per pixel) transparency in OCX with the following routine:
Code:
Public Function LoadPictureGDIPlus(ByVal pstrPicFile As String, ByRef pobjIPicture As IPicture, Optional ByVal plngDestWidth As Long = -1, Optional ByVal plngDestHeight As Long = -1, Optional ByRef plngSrcWidth As Long = 0, Optional ByRef plngSrcHeight = 0, Optional ByVal plngBackColor As Long = lngTransparency, Optional ByRef pblnRetainRatio As Boolean = True, Optional ByVal penmInterpolation As InterpolationModeEnum = InterpolationModeEnum.[3 - enmNearestNeighbor]) As Long
Dim lngRetValue As Long
Dim lngSuccess As Long
Dim lngHdc As Long
Dim lngHBitmap As Long
Dim lngImg As Long
Dim ptrPicFile As Long
'Assume Fail
lngRetValue = 0
'Err.Raise 13, "GDI+ Module", "Error loading picture [" & pstrPicFile & "]"
' Load the image
ptrPicFile = StrPtr(pstrPicFile)
lngSuccess = GdipLoadImageFromFile(ptrPicFile, lngImg)
If (lngSuccess = 0) Then
'Get real Size
lngSuccess = GdipGetImageWidth(lngImg, plngSrcWidth)
lngSuccess = GdipGetImageHeight(lngImg, plngSrcHeight)
If (plngDestWidth = -1) Then
plngDestWidth = plngSrcWidth
End If
If (plngDestHeight = -1) Then
plngDestHeight = plngSrcHeight
End If
' Initialise the hDC
InitDC lngHdc, lngHBitmap, plngBackColor, plngDestWidth, plngDestHeight
' Resize the picture
GdipResize lngImg, lngHdc, plngDestWidth, plngDestHeight, pblnRetainRatio, penmInterpolation
lngSuccess = GdipDisposeImage(lngImg)
' Get the bitmap back
GetBitmap lngHdc, lngHBitmap
' Create the picture
lngSuccess = CreatePicture(lngHBitmap, pobjIPicture)
lngRetValue = 1
End If
LoadPictureGDIPlus = lngRetValue
End Function
and the important function:
Code:
' Creates a Picture Object from a handle to a bitmap
Private Function CreatePicture(ByVal plngHBitmap As Long, ByRef pobjIPicture As IPicture) As Long
Dim lngRetValue As Long
Dim typGuid As GUID
Dim typPicDesc As PICTDESC
' Fill in OLE IDispatch Interface ID
typGuid.Data1 = &H20400
typGuid.Data4(0) = &HC0
typGuid.Data4(7) = &H46
' Fill typPicDesc with necessary parts
typPicDesc.size = Len(typPicDesc) ' Length of structure
typPicDesc.Type = PICTYPE_BITMAP ' Type of Picture (bitmap)
typPicDesc.hBmp = plngHBitmap ' Handle to bitmap
' Create the picture
lngRetValue = OleCreatePictureIndirect(typPicDesc, typGuid, True, pobjIPicture)
'Set CreatePicture = pobjIPicture
CreatePicture = lngRetValue
End Function
it's eyes candy for me
-
Feb 13th, 2018, 03:51 PM
#5
Re: Get image size of IPicture with GDI routine
Let's see these functions: GetBitmap and also InitDC
I don't see an immediate problem with anything you posted
Also, you should check the return value of CreatePicture. If successful, that value should be zero.
-
Feb 13th, 2018, 04:40 PM
#6
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
Let's see these functions: GetBitmap and also InitDC
I don't see an immediate problem with anything you posted
Also, you should check the return value of CreatePicture. If successful, that value should be zero.
yes, it does return 0, S_OK = 0. The guy that made the code didn't used Long for function (wich I hate)
he was doing:
Set mIPicture = CreatePicture(...)
I modified all function so the IPicture object is passed as parameter, therefore, all value returned by theses fonction are mine.
However and I checked them with MSDN specification, all seem ok.
Code:
' Replaces the old bitmap of the hDC, Returns the bitmap and Deletes the hDC
Private Sub GetBitmap(ByVal plngHdc As Long, ByRef plngHBitmap As Long)
Dim lngSuccess As Long
plngHBitmap = SelectObject(plngHdc, plngHBitmap)
lngSuccess = DeleteDC(plngHdc)
End Sub
Code:
' Initialises the hDC to draw
Private Sub InitDC(ByRef plngHdc As Long, ByRef plngHBitmap As Long, ByVal plngBackColor As Long, ByVal plngWidth As Long, ByVal plngHeight As Long)
Dim lngHBrush As Long
' Create a memory DC and select a bitmap into it, fill it in with the backcolor
plngHdc = CreateCompatibleDC(ByVal 0&)
plngHBitmap = CreateBitmap(plngWidth, plngHeight, GetDeviceCaps(plngHdc, PLANES), GetDeviceCaps(plngHdc, BITSPIXEL), ByVal 0&)
plngHBitmap = SelectObject(plngHdc, plngHBitmap)
lngHBrush = CreateSolidBrush(plngBackColor)
lngHBrush = SelectObject(plngHdc, lngHBrush)
PatBlt plngHdc, 0, 0, plngWidth, plngHeight, PATCOPY
DeleteObject SelectObject(plngHdc, lngHBrush)
End Sub
I made over 300 small modification on the code to ehnance it. what I didn't do yet is check if all created object are deleted to avoid memory leak.
-
Feb 13th, 2018, 05:04 PM
#7
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
I got a question...
if I'm using StretchBlt (from GDI32)
can I set it to work with GdipSetInterpolationMode() ?
if not, what the best way to stretch an IPicture using NearestNeighbor ?
thanks
I should have named this thread help with GDI+ :S
-
Feb 13th, 2018, 06:42 PM
#8
Re: Get image size of IPicture with GDI routine
My gut feeling for your problems is that you somehow created an IPicture on the bitmap that came with the new DC you created and not the bitmap you created from CreateBitmap. You can verify that...
1. in your InitDC function, debug.print plngHBitmap returned from CreateBitmap
2. in your CreatePicture function, debug.print plngHBitmap
Are they the same values?
If not, maybe they got swapped somehow in your GdipResize function (which we haven't seen).
Now regarding your other question. GdipSetInterpolationMode should be used in your GdipResize function when you render the GDI+ image to the target DC. There is no way to directly mix GDI and GDI+. In fact, when GDI+ creates an hGraphics object on a GDI hDC, you should not be calling any GDI APIs on that DC until you destroy that GDI+ hGraphics object
-
Feb 13th, 2018, 07:29 PM
#9
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
My gut feeling for your problems is that you somehow created an IPicture on the bitmap that came with the new DC you created and not the bitmap you created from CreateBitmap. You can verify that...
1. in your InitDC function, debug.print plngHBitmap returned from CreateBitmap
2. in your CreatePicture function, debug.print plngHBitmap
Are they the same values?
If not, maybe they got swapped somehow in your GdipResize function (which we haven't seen).
Now regarding your other question. GdipSetInterpolationMode should be used in your GdipResize function when you render the GDI+ image to the target DC. There is no way to directly mix GDI and GDI+. In fact, when GDI+ creates an hGraphics object on a GDI hDC, you should not be calling any GDI APIs on that DC until you destroy that GDI+ hGraphics object
I apreciated your deep knowledge of the subject.
<<Are they the same values?
I checked the first value of plngHBitmap on the CreateBitmap()
and yes, they are ok, I checked as you suggested.
I was wondering 2 thing in InitDC()
is that ok to reuse plngHBitmap that way ?
plngHBitmap = SelectObject(plngHdc, plngHBitmap)
because we're returning the second value. (byref)
I'm guessing since it's a selectObject (returning previous object) we'll use the new value later to delete it and passing back the old value.
so here the other subroutine:
Code:
' Resize the picture using GDI plus
Public Sub GdipResize(ByRef plngImg As Long, ByVal plngHdc As Long, ByVal plngWidth As Long, ByVal plngHeight As Long, Optional ByVal pblnRetainRatio As Boolean = True, Optional ByVal penmInterpolation As InterpolationModeEnum = InterpolationModeEnum.[3 - enmNearestNeighbor])
Dim lngGraphics As Long ' Graphics Object Pointer
Dim lngOrWidth As Long ' Original Image Width
Dim lngOrHeight As Long ' Original Image Height
Dim dblOrRatio As Double ' Original Image Ratio
Dim dblDesRatio As Double ' Destination rect Ratio
Dim lngDestX As Long ' Destination image X
Dim lngDestY As Long ' Destination image Y
Dim lngDestWidth As Long ' Destination image Width
Dim lngDestHeight As Long ' Destination image Height
Dim lngRetValue As Long
lngRetValue = GdipCreateFromHDC(plngHdc, lngGraphics)
lngRetValue = GdipSetInterpolationMode(lngGraphics, penmInterpolation)
If (pblnRetainRatio = True) Then
lngRetValue = GdipGetImageWidth(plngImg, lngOrWidth)
lngRetValue = GdipGetImageHeight(plngImg, lngOrHeight)
dblOrRatio = (lngOrWidth / lngOrHeight)
dblDesRatio = (plngWidth / plngHeight)
' Calculate destination coordinates
lngDestWidth = IIf(dblDesRatio < dblOrRatio, plngWidth, plngHeight * dblOrRatio)
lngDestHeight = IIf(dblDesRatio < dblOrRatio, plngWidth / dblOrRatio, plngHeight)
'lngDestX = (plngWidth - lngDestWidth) \ 2
'lngDestY = (plngHeight - lngDestHeight) \ 2
lngDestX = 0
lngDestY = 0
lngRetValue = GdipDrawImageRectRectI(lngGraphics, plngImg, lngDestX, lngDestY, lngDestWidth, lngDestHeight, 0, 0, lngOrWidth, lngOrHeight, UnitPixel, 0, 0, 0)
Else
lngRetValue = GdipDrawImageRectI(lngGraphics, plngImg, 0, 0, plngWidth, plngHeight)
End If
lngRetValue = GdipDeleteGraphics(lngGraphics)
End Sub
-
Feb 13th, 2018, 07:34 PM
#10
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
when GDI+ creates an hGraphics object on a GDI hDC, you should not be calling any GDI APIs on that DC until you destroy that GDI+ hGraphics object
didn't know that.... I was using AlphaBlend() and a StretchBlt() on the DC before calling the FreeGDIPlus lngToken
maybe that explain why on some occasion IDE crash on mouse over the IPicture.width element.
I just changed it. I didn't needed to keep the DC open after the LoadPictureGDIPlus() anyway.
-
Feb 13th, 2018, 09:09 PM
#11
Re: Get image size of IPicture with GDI routine
Sorry took so long to get back to you. I don't think I've ever seen OleCreatePictureIndirect used directly with IDispatch as you are doing in your CreatePicture function and that may be the problem? Try using this instead & let us know if results change.
Code:
Private Function CreatePicture(ByVal plngHBitmap As Long, ByRef pobjIPicture As IPicture) As Long
Dim lngRetValue As Long
Dim typGuid As Guid
Dim typPicDesc As PICTDESC
Dim aGUID(0 To 3) As Long
' Fill typPicDesc with necessary parts
typPicDesc.Size = Len(typPicDesc) ' Length of structure
typPicDesc.Type = PICTYPE_BITMAP ' Type of Picture (bitmap)
typPicDesc.hBmp = plngHBitmap ' Handle to bitmap
' Fill in OLE IPicture Interface ID
aGUID(0) = &H7BF80980
aGUID(1) = &H101ABF32
aGUID(2) = &HAA00BB8B
aGUID(3) = &HAB0C3000
' create stdPicture
lngRetValue = OleCreatePictureIndirect(typPicDesc, aGUID(0), True, pobjIPicture)
'Set CreatePicture = pobjIPicture
CreatePicture = lngRetValue
End Function
Note: I used an array for the GUID so if needed, change your API OleCreatePictureIndirect second parameter to:
ByRef parameterName As Any
Regarding GDI+ and GDI interoperability. You misunderstood. I did not mean you needed to shut down GDI+, I just mean that you should call GdipDeleteGraphics before using any GDI drawing APIs on a DC wrapped in GDI+ hGraphics. Your code is doing that.
-
Feb 13th, 2018, 11:19 PM
#12
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
Sorry took so long to get back to you.
meh! You're the fastest answer I got and the one I was awaiting for. I applaude your willingness to help me
Originally Posted by LaVolpe
I don't think I've ever seen OleCreatePictureIndirect used directly with IDispatch as you are doing in your CreatePicture function and that may be the problem?
some part of this code is way out of my leagues. I don't do graphics, I'm a database and SQL programist. Logic and Array are easy for me. Graphics and GDI+, the most I know come from you and your AIC. Otherwise, I don't do graphics.
Originally Posted by LaVolpe
Note: I used an array for the GUID so if needed, change your API OleCreatePictureIndirect second parameter to:
ByRef parameterName As Any
will do but still faill to understand the change you did... I'll analyze the memory value and come back at you.
Originally Posted by LaVolpe
Regarding GDI+ and GDI interoperability. You misunderstood. I did not mean you needed to shut down GDI+, I just mean that you should call GdipDeleteGraphics before using any GDI drawing APIs on a DC wrapped in GDI+ hGraphics. Your code is doing that.
oh... k.... make sense.
-
Feb 13th, 2018, 11:25 PM
#13
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Hi Lavolpe.
I check the code and I don't understand the value you're using for [riid] param in OleCreatePictureIndirect
can you explain to me or point out to documentation ??
since value you use are different then thoses I previously use.
thanks.
Edit: Still don't know where you took thoses value. I understand you traded 16 bytes for 16 differents bytes. still looking the documenation about it. I tried it and it work. I prefer to use a type GUID_I composed of 4 long instead of array, I don't like the as any type but it's all the same.
Code:
Private Declare Function OleCreatePictureIndirectGuidI Lib "olepro32.dll" Alias "OleCreatePictureIndirect" (ByRef PicDesc As PICTDESC, ByRef RefIID As GUIDI, ByVal fPictureOwnsHandle As Long, ByRef IPic As IPicture) As Long
Private Type GUIDI
Data1 As Long
Data2 As Long
Data3 As Long
Data4 As Long
End Type
Dim typGuidI As GUIDI
' Fill in OLE [IPicture] Interface ID and create the picture
typGuidI.Data1 = &H7BF80980
typGuidI.Data2 = &H101ABF32
typGuidI.Data3 = &HAA00BB8B
typGuidI.Data4 = &HAB0C3000
lngRetValue = OleCreatePictureIndirectGuidI(typPicDesc, typGuidI, True, pobjIPicture)
Last edited by VbNetMatrix; Feb 13th, 2018 at 11:49 PM.
-
Feb 14th, 2018, 07:37 AM
#14
Re: Get image size of IPicture with GDI routine
Originally Posted by VbNetMatrix
Hi Lavolpe.
I check the code and I don't understand the value you're using for [riid] param in OleCreatePictureIndirect
can you explain to me or point out to documentation ??
The IID is: 7BF80980-BF32-101A-8BBB-00AA00300CAB
Here is the documentation
but still faill to understand the change you did
I changed the interface from IDispatch to IPicture.
-
Feb 14th, 2018, 08:52 AM
#15
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
The IID is: 7BF80980-BF32-101A-8BBB-00AA00300CAB
Here is the documentation
I changed the interface from IDispatch to IPicture.
Sorry, I faulty explained myself....what I meant was : I understood you changed the IDispatch to IPicture interface from your comment, I didn't understood the hex value because I couldn't find the documentation about it. that's what I meant.
I'm not sure why the IDispatch was working I'll look more at documentation you gave.
there again, I apreciate your wisdom. My component is almost finished, I would like to dedicate it to you and to post it as my first project on VbForum.
I think you'll find it interesting because I'm using unusual technique for my OCX (wich allow me to use a template creator for all my OCX) soon I'll post to you in private a link where you can download the source.
I'm left with only 1 problem... how to translate IPicture into byte() array back and forth...
I think I found 1 of the solution but not the other... can't test it without both! lol.
thanks again for all your help.
-
Feb 14th, 2018, 09:34 AM
#16
Re: Get image size of IPicture with GDI routine
Originally Posted by VbNetMatrix
Sorry, I faulty explained myself....what I meant was : I understood you changed the IDispatch to IPicture interface from your comment, I didn't understood the hex value because I couldn't find the documentation about it. that's what I meant...
I'm left with only 1 problem... how to translate IPicture into byte() array back and forth...
I think I found 1 of the solution but not the other... can't test it without both!
I use an API to convert string GUIDs to 16 byte values. This API requires the enclosed curly braces, but is not case-sensitive
Code:
Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpszProgID As Long, piid As Any) As Long
' sample of getting the IDataObject GUID.
Dim aGUID(0 To 3) As Long
Call IIDFromString(StrPtr("{0000010e-0000-0000-C000-000000000046}"), ByVal VarPtr(aGUID(0)))
As far as saving IPicture to bytes, not sure how that will be useful? The CreatePicture routine you have is creating a bitmap, no transparency. You don't have the original bytes any longer. You might want to consider saving the bytes earlier in the process? If you don't care about the original bytes, which may be PNG format for example, then there are lots of sample code about to convert a bitmap handle (stdPicture/IPicture.Handle) to array. In fact, you could actually use VB's SavePicture to file then open file & get bytes that way -- but not a pretty solution.
Edited: If you are concerned with bytes for your usercontrol's WriteProperties event and only need to save the bitmap, you don't need bytes. You can simply save the stdPicture/IPicture object directly
Last edited by LaVolpe; Feb 14th, 2018 at 09:41 AM.
-
Feb 14th, 2018, 11:53 AM
#17
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
I use an API to convert string GUIDs to 16 byte values. This API requires the enclosed curly braces, but is not case-sensitive
Code:
Private Declare Function IIDFromString Lib "ole32.dll" (ByVal lpszProgID As Long, piid As Any) As Long
' sample of getting the IDataObject GUID.
Dim aGUID(0 To 3) As Long
Call IIDFromString(StrPtr("{0000010e-0000-0000-C000-000000000046}"), ByVal VarPtr(aGUID(0)))
I have noticed the high bit and low bit are reversed. Probably because how memory store value.
although not really related to our problem, I found this:
http://codes-sources.commentcamarche...controle-image
therefore, I understand your value from "7BF80980-BF32-101A-8BBB-00AA00300CAB"
Code:
'typGUID.Data1 = &H7BF80980
'typGUID.Data2 = &H101ABF32
'typGUID.Data3 = &HAA00BB8B
'typGUID.Data4 = &HAB0C3000
can be translated as:
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
typGUID.Data1 = &H7BF80980
typGUID.Data2 = &HBF32
typGUID.Data3 = &H101A
typGUID.Data4(0) = &H8B
typGUID.Data4(1) = &HBB
typGUID.Data4(2) = &H0
typGUID.Data4(3) = &HAA
typGUID.Data4(4) = &H0
typGUID.Data4(5) = &H30
typGUID.Data4(6) = &HC
typGUID.Data4(7) = &HAB
and I do not have to reverse any bit.
I tested it and it work.
Originally Posted by LaVolpe
As far as saving IPicture to bytes, not sure how that will be useful? The CreatePicture routine you have is creating a bitmap, no transparency. You don't have the original bytes any longer. You might want to consider saving the bytes earlier in the process? If you don't care about the original bytes, which may be PNG format for example, then there are lots of sample code about to convert a bitmap handle (stdPicture/IPicture.Handle) to array. In fact, you could actually use VB's SavePicture to file then open file & get bytes that way -- but not a pretty solution.
Edited: If you are concerned with bytes for your usercontrol's WriteProperties event and only need to save the bitmap, you don't need bytes. You can simply save the stdPicture/IPicture object directly
damn... I didn't know I could simply save the IPicture in property. I wonder if that will retain the transparency I kept.
I'll go try
THANKS A LOT your knowledge on the subject is eye opening for me.
the idea of saving the bytes early is also an idea to consider... I'll see if it is required, for now, the transparency and Alpha are maintained.
-
Feb 14th, 2018, 12:47 PM
#18
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by VbNetMatrix
I'll see if it is required, for now, the transparency and Alpha are maintained.
I saved the IPicture directly as suggested.
I confirm the IPicture can be saved that way, I can retrieve the content on a picture box.
but my OCX fail to print it directly on the OCX when the project is reopened in IDE.
it is "saving" the IPicture but I think something is loss.
before closing the IDE, I confirmed both, the hidden picture box and direct print on the OCX is working.
maybe I got a bug in my code... I'll check furthermore this afternoon.
-
Feb 14th, 2018, 04:08 PM
#19
Re: Get image size of IPicture with GDI routine
but my OCX fail to print it directly on the OCX when the project is reopened in IDE...
maybe I got a bug in my code.
If you are drawing your picture to your usercontrol, you may need to use AutoRedraw=True or respond to the Paint events. But having the IPicture/stdPicture interface, this should work too: Set UserControl.Picture = yourCachedIPicture
Of course you would retrieve your saved picture from ReadProperties using the same property name you gave it in WriteProperties.
-
Feb 14th, 2018, 05:21 PM
#20
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
If you are drawing your picture to your usercontrol, you may need to use AutoRedraw=True or respond to the Paint events. But having the IPicture/stdPicture interface, this should work too: Set UserControl.Picture = yourCachedIPicture
Of course you would retrieve your saved picture from ReadProperties using the same property name you gave it in WriteProperties.
yeah I'm aware of the autoredraw but that's not the problem. It's showing the image properly before I close IDE
and showing garbabge when I open it back.
I tried with bigger picture and I realized the "gargage" was in fact a picture of upper left corner of screen where you can read:
"Project1 - Microsoft Visual Basic"
but like a NOT blue "mask"
in other word, I got a picture, but not the one I got recorder... strangly, the picture I got recorder get assigned in the picturebox holder but NOT in the IPicture object....
puzzle me...
here what I did:
Code:
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
Set mobjIPicture = PropBag.ReadProperty("Picture", Nothing)
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "Picture", mobjIPicture, Nothing
what am I missing ?
-
Feb 14th, 2018, 07:24 PM
#21
Re: Get image size of IPicture with GDI routine
Can you make sure that mobIPicture is what you expect. Maybe something like the following, just before it is written to the propertybag.
Code:
Clipboard.Clear
Clipboard.SetData mobjIPicture
Then go and paste the image into Paint and verify.
If that was verified, then maybe doing this may solve the problem? But I doubt it and is just a guess at best.
Code:
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
Dim tPic As stdPicture
Set tPic = mobjIPicture
PropBag.WriteProperty "Picture", tPic, Nothing
...
End Sub
Likewise, you can use the Clipboard test when you read the picture from the propertybag, just as a test.
-
Feb 14th, 2018, 10:40 PM
#22
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
Can you make sure that mobIPicture is what you expect. Maybe something like the following, just before it is written to the propertybag.
Code:
Clipboard.Clear
Clipboard.SetData mobjIPicture
Then go and paste the image into Paint and verify.
If that was verified, then maybe doing this may solve the problem? But I doubt it and is just a guess at best.
Code:
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
Dim tPic As stdPicture
Set tPic = mobjIPicture
PropBag.WriteProperty "Picture", tPic, Nothing
...
End Sub
Likewise, you can use the Clipboard test when you read the picture from the propertybag, just as a test.
thanks Lavolpe.
I tried your suggestion... I was still puzzle because everything looked fine...
so I decided to make a simple test project.
a simple OCX that show a BMP but saving and reading the BMP (instead of png) as IPicture
and... it worked...
so I started to use same syntax and same variable to get where there was a mismatch...
well... as you know... and you'll laugh because you probably had that bug in the past.,
IPicture is not in the auto complete of the IDE and when you type IPicture , sometime it get completed to
IPictuteDisp
for some reason, as long as I don't quit the IDE, it was working but when I left IDE and load back, the image was somehow corrupted.
I'm doing the modification right now, I'll keep you informed.
-
Feb 15th, 2018, 12:09 AM
#23
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
The IPictureDisp bug didn't fix the problem...
same thing...
I'm really puzzled. maybe too tired... tomorow is another day.
-
Feb 15th, 2018, 07:39 AM
#24
Re: Get image size of IPicture with GDI routine
well... as you know... and you'll laugh because you probably had that bug in the past.,
IPicture is not in the auto complete of the IDE and when you type IPicture , sometime it get completed to
IPictuteDisp
Tip: If you are referencing "hidden" objects in VB, if you open the object explorer (F2) and right click in the bottom right "members" listview and select "Show hidden members", they will become visible to VB's intellisense/autocomplete
-
Feb 15th, 2018, 11:20 AM
#25
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Originally Posted by LaVolpe
Tip: If you are referencing "hidden" objects in VB, if you open the object explorer (F2) and right click in the bottom right "members" listview and select "Show hidden members", they will become visible to VB's intellisense/autocomplete
Sometime I wonder if there is someting you don't know about Vb6
as for me... I really consider myself... a high level user... but still, I believe I have touch only a fraction of what Vb6 had to offer. sad choice Microsoft did in 1998.
Edit: the problem still elude me. after the property is saved and loaded back, the image can be put in picture box but not directly on the ocx dc... still checking...
there is also that bug I found a way out but don't know where it came out where when component finish loading, a resize event is fired and usercontrol gain 1pixel height and width. I had to make special check for that.
-
Feb 15th, 2018, 01:58 PM
#26
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
ok... I found the problem... but at first I was stuck with my INITIAL problem
I'm using AlphaBlend() Api with AC_SRC_ALPHA flag
The AlphaBlend flag FAIL if there is no transparency in the picture.
everything work as long as the property is not saved because somehow, iPicture and even StdPicture keep transparency in memory as long as you don't save theses as property. When you load them from property, transparency is gone.
and AlphaBlend (silently) FAIL because of AC_SRC_ALPHA flag. There is no error, just no output
However. I have designed a way so the PNG transparency is replaced with WHITE color and I can now afford not using the AC_SRC_ALPHA flag...
hourray !
not perfect though, my preview box doesn't work the way it did, I'll have to find a workaround.
-
Feb 18th, 2018, 11:44 PM
#27
Thread Starter
Addicted Member
Re: Get image size of IPicture with GDI routine
Hi Lavolpe,
you'll be glad to know that I arrived at a decent solution...
only glitch are Alphachannel... not good... but regular (background) transparency work well
not sure how I could get the quality you get with your AIC... I'm not sure how you show the original Data of the png on the the ocx I have simply used AlphaBlend api
I think you'll like when you'll see the source... I'll send you a link soon.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|