Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help with IPictureDisp.. URGENT Pls ! 1

Status
Not open for further replies.

vbSun

Programmer
Dec 9, 2002
504
US
Hello experts,

I want to create an hdc for IPictureDisp object available.. Is it possible?

Pls help me out..

thanks in advance..
Sunil
 
Technically IPictureDisp isn't a class and certainly isn't an object, is is an interface (although I appreciate that VB tends to blur the distinctions).

The StdPicture class (which is what VB generally calls Picture) exposes the IPictureDisp interface as the primary interface for a Picture object, although it is also possible to expose the IPicture interface instead.

Now, the IPictureDisp interface does not have any HDC properties, and you can't modify the interface ti=o support one (you would be breaking the COM contract if you could). It is also worth pointing out that a bitmap (which is all that IPicture and IPictureDisp really represent) does not have an inherent hDC - a bitmap gets associated with an hDC by being selected into one

You have several alternatives, however. You can create your own interface (or class) that implements IPictureDisp and extends it, or you can use the IPicture interface of a Picture object (which does have hDC properties, once you select the bitmap it represents into an hDC).

Here's a simple example of the latter(you need a form with a picturebox and a command button):
[tt]
Option Explicit

Private Sub Command1_Click()
Dim myPicture As IPicture ' myPicture is an object that implements the IPicture interface

Set myPicture = Picture1.Picture ' Get the IPicture interface of Picture1.Picture
myPicture.SelectPicture Picture1.hDC, 0&, 0& ' Select the picture into an HDC

MsgBox myPicture.CurDC ' Return the hDC the picture is currently selected into

End Sub
[/tt]
Okey dokey. Now that illustrates the principal. But what you really want to do is have your own private hDC (rather than using one that belongs to a control on a form). For that we have to get into the API, but it is pretty straightforward. This example just requires a form with a command button:
[tt]
Option Explicit

Private Const SRCCOPY = &HCC0020
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long

Private Sub Command1_Click()
Dim myPicture As IPicture ' myPicture is an object that implements the IPicture interface

Set myPicture = LoadPicture("c:\word.bmp") ' Get the IPicture interface of the loaded OLE Picture; load your own image here
myPicture.SelectPicture vbGetCompatibleDC(), 0&, 0& ' Select the picture into a screen-compatible memory DC

MsgBox myPicture.CurDC ' Return the hDC the picture is currently selected into

' Next line just demonstrates a typical use of an hDC
BitBlt Form1.hdc, 0, 0, myPicture.Width, myPicture.Height, myPicture.CurDC, 0, 0, SRCCOPY
End Sub

Public Function vbGetCompatibleDC() As Long
' Create a screen-compatible memory DC
vbGetCompatibleDC = CreateCompatibleDC(GetDC(0)) ' screen compatible
End Function
[/tt]
 
Thanks StrongM,

That clarified something.. am playing with it, will come back as soon as i make something outof this information..

Thanks a lot,
Sunil
 
Om Still on it strongm..

Trying to digest the fact that iPicDisp cannot be a class and an object of it cannot be created, and moreover it has no hdc. Now am trying to replace it with iPicture, and do some processing of image in memory and later trying to copy it to another iPicture object and return back from the function.

Prototype will be something like..

Function process (iDest as IPicture) as IPicture

Sad to say am not an inch forward yet...

Thanks for getting back to me.. i definitely need some more help....
 
Hi StrongM,

I have been trying my luck with the IPicture, and still i found very minimum.. i think am getting stuck in some points, I cant even imagine of a Picture Object in memory and manipulating and copying it to another.. its like trying to figure out the road map of a country where I have never been!

Pls Help...

'This is the function i use (thanks!) to create the DC
Public Function vbGetCompatibleDC() As Long
' Create a screen-compatible memory DC
vbGetCompatibleDC = CreateCompatibleDC(GetDC(0)) ' screen compatible
End Function


Public Function BitRotate(ByRef Source As IPicture, ByVal Angle As Double, ByVal AntiAlias As Boolean) As IPicture
'Store a few attributes of the pictures for increased speed
Dim tmpPic As IPicture
Set tmpPic = Source
' tmpPic.Width = Source.Width
' tmpPic.Height = Source.Height
SourceWidth = Source.Width / Screen.TwipsPerPixelX
SourceHeight = Source.Height / Screen.TwipsPerPixelY
DestWidth = tmpPic.Width / Screen.TwipsPerPixelX
DestHeight = tmpPic.Height / Screen.TwipsPerPixelY
Source.SelectPicture vbGetCompatibleDC(), 0&, 0&
'Allocate array for source picture's bits
ReDim SourceBuffer.Bits(3, SourceWidth - 1, SourceHeight - 1)
With SourceBuffer.Header
.biSize = 40
.biWidth = SourceWidth
.biHeight = -SourceHeight
.biPlanes = 1
.biBitCount = 32
.biSizeImage = 3 * SourceWidth * SourceHeight
End With
'Get source pictures bits
GetDIBits Source.CurDC, Source.Handle, 0, SourceHeight, SourceBuffer.Bits(0, 0, 0), SourceBuffer, 0&

'Allocate array for dest picture's bits
ReDim DestBuffer.Bits(3, DestWidth - 1, DestHeight - 1)
With DestBuffer.Header
.biSize = 40
.biWidth = DestWidth
.biHeight = -DestHeight
.biPlanes = 1
.biBitCount = 32
.biSizeImage = 3 * DestWidth * DestHeight
End With

'Get center of source picture
cx = SourceWidth * 0.5
cy = SourceHeight * 0.5

'Get center of destination picture
dx = DestWidth * 0.5
dy = DestHeight * 0.5

'Convert angle to Sin/Cos radians
cosa = Cos(Angle * Deg2Rad * -1)
sina = Sin(Angle * Deg2Rad * -1)

'Get bounds of source picture
biW = SourceWidth - 1
biH = SourceHeight - 1
SetRect biRct, 0, 0, biW, biH

'Clear dectination picture
'Dest.Cls
For y = 0 To DestHeight - 1
'Destination Y to calculate
yin = y - dy
For x = 0 To DestWidth - 1
'Destination X to calculate
xin = x - dx

'Rotate destination X, Y according to angle in radians
rx = xin * cosa - yin * sina + cx
ry = xin * sina + yin * cosa + cy

'Round of rotated pixels X, Y coordinates
irx = Int(rx)
iry = Int(ry)

'If rotated pixel is within bounds of destination
If (PtInRect(biRct, irx, iry)) Then

'Convert pixel to destination
drx = rx - irx
dry = ry - iry

'If Anti-Alias switch is on
If AntiAlias Then
'Get rotated pixel
r1 = SourceBuffer.Bits(2, irx, iry)
g1 = SourceBuffer.Bits(1, irx, iry)
b1 = SourceBuffer.Bits(0, irx, iry)

'Get rotated pixels right neighbor
r2 = SourceBuffer.Bits(2, irx + 1, iry)
g2 = SourceBuffer.Bits(1, irx + 1, iry)
b2 = SourceBuffer.Bits(0, irx + 1, iry)

'Get rotated pixels lower neighbor
r3 = SourceBuffer.Bits(2, irx, iry + 1)
g3 = SourceBuffer.Bits(1, irx, iry + 1)
b3 = SourceBuffer.Bits(0, irx, iry + 1)

'Get rotated pixels lower right neighbor
r4 = SourceBuffer.Bits(2, irx + 1, iry + 1)
g4 = SourceBuffer.Bits(1, irx + 1, iry + 1)
b4 = SourceBuffer.Bits(0, irx + 1, iry + 1)

'Interpolate pixels along Y axis
ib1 = b1 * (1 - dry) + b3 * dry
ig1 = g1 * (1 - dry) + g3 * dry
ir1 = r1 * (1 - dry) + r3 * dry
ib2 = b2 * (1 - dry) + b4 * dry
ig2 = g2 * (1 - dry) + g4 * dry
ir2 = r2 * (1 - dry) + r4 * dry

'Interpolate pixels along X axis
B = ib1 * (1 - drx) + ib2 * drx
G = ig1 * (1 - drx) + ig2 * drx
R = ir1 * (1 - drx) + ir2 * drx

'Check for valid color range
If (R < 0) Then R = 0 Else If (R > 255) Then R = 255
If (G < 0) Then G = 0 Else If (G > 255) Then G = 255
If (B < 0) Then B = 0 Else If (B > 255) Then B = 255

'Plot interpolated pixel to destination picture
DestBuffer.Bits(2, x, y) = R
DestBuffer.Bits(1, x, y) = G
DestBuffer.Bits(0, x, y) = B
Else
'Get rotated pixel
R = SourceBuffer.Bits(2, irx, iry)
G = SourceBuffer.Bits(1, irx, iry)
B = SourceBuffer.Bits(0, irx, iry)

'Plot rotated pixel to destination picture
DestBuffer.Bits(2, x, y) = R
DestBuffer.Bits(1, x, y) = G
DestBuffer.Bits(0, x, y) = B
End If
End If
Next x
Next y
'Load destination bits to destination picture
SetDIBits tmpPic.CurDC, tmpPic.Handle, 0, DestHeight, DestBuffer.Bits(0, 0, 0), DestBuffer, 0&
Set BitRotate = tmpPic
End Function


Looking eagerly for your reply...
Thanks,
Sunil
 
Ah - you just want to rotate a bitmap. Which operating system are you targetting. I have a much more efficient way of rotating bitmaps than the 'classic' example that you are trying to use...
 
Operating system? I think its for all win platforms... I will actually take anything that can rotate the picture in memory and return the rotated bitmap back...

SAD.. its getting harder..
 
I looked at it strong m, but it says even Win98 is not supported.. I admit it may be the best way, but am sure i want it to work in Win98 !!!
 
I also responded ? &quot;its for all win platforms&quot; ....

 
Hmm.. i dont know whether you will respond again in this thread...

anyway.. thanks for all the help and advice.. you surely are better than what everyone thinks...


Thanks Strongm
 
I'm glad you've managed to get it sorted.

(shame you couldn't use the SetWorldTransform idea though ;-))
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top