|
-
Apr 4th, 2010, 01:48 PM
#1
[VB] stdPicture Render (How To)
What is the .Render method of the stdPicture object and how does one use it.
FYI: a stdPicture object is either an object declared as stdPicture or any VB .Picture/.Image property, including those of forms, image controls, pictureboxes, etc. Some other properties may be stdPicture objects too, like a command button's .DisabledPicture property or a form's .Icon property.
The .Render method has all the benefits of VB's PaintPicture method, except one, and has a few additional benefits that VB's PaintPicture does not. In short, you have some more flexibility with .Render, but its usage is not widely known or understood.
What does PaintPicture do that .Render cannot? It can render a stdPicture object with different raster operations, i.e., vbSrcPaint, vbSrcErase, etc. The .Render method cannot by itself. SetROP2 API can do the job though.
What does .Render do that PaintPicture cannot? A few things
1. It can render to any DC, memory DC, DC returned by API, or VB .hDC property (major advantage)
2. It can render transparent GIFs, maintaining transparency (minor advantage)
3. It is faster because less VB overhead is involved
What APIs do PaintPicture & .Render replicate? BitBlt, StretchBlt, DrawIcon, DrawIconEx and metafile rendering. So you see, you have some powerful API replication in some common VB methods.
Why is .Render not understood well? Because it is harder to use and PaintPicture can suffice a vast majority of the time and is easier to use. To understand .Render, you need to understand a bit about bitmaps and .Render's parameter requirements
a. Destination parameters for .Render are in pixels
b. Source parameters for .Render are in himetrics
c. stdPicture objects are DIBs, stored upside down. So source parameters must be flipped vertically when rendering.
Knowing the above, one can build a custom Render function using a stdPicture object. The following includes options for: stretching, scaling, offsetting, centering, partial rendering, and user-defined scalemodes.
Simply copy & paste to your project. Commented well in the code.
Tip: To make copying easier, hit the "Quote" button below & copy from that window.
vb Code:
Private Function RenderStdPicture(theTarget As Variant, thePic As StdPicture, _ Optional ByVal destX As Single, Optional ByVal destY As Single, _ Optional ByVal destWidth As Single, Optional ByVal destHeight As Single, _ Optional ByVal srcX As Single, Optional ByVal srcY As Single, _ Optional ByVal srcWidth As Single, Optional ByVal srcHeight As Single, _ Optional ByVal ParamScaleMode As ScaleModeConstants = vbUser, _ Optional ByVal Centered As Boolean = False, Optional ByVal ZoomFactor As Single = 1&) As Boolean ' Return Value [out] ' If no errors occur, return value is True. If error or invalid parameters passed, value is False ' Parameters [in] ' theTarget: a VB form, picturebox, usercontrol or a valid hDC (no error checking for valid DC) ' ... If Object, then it must expose a ScaleMode and hDC property ' ... and if centering and an object, must also expose ScaleWidth & ScaleHeight properties ' thePic: a VB ImageControl, stdPicture object, or VB .Picture property ' destX: horizontal offset on theTarget where drawing begins, default is zero ' destY: vertical offset on theTarget where drawing begins, default is zero ' destWidth: rendered image width & will be multiplied against ZoomFactor; default is thePic.Width ' destHeight: rendered image height & will be multiplied against ZoomFactor; default is thePic.Height ' srcX: horizontal offset of thePic to begin rendering from; default is zero ' srcY: vertical offset of thePic to begin rendering from; default is zero ' srcWidth: thePic width that will be rendered; default is thePic.Width ' srcHeight: thePic height that will be rendered; default is thePic.Height ' ParamScaleMode: Scalemode for passed parameters. ' If vbUser, then theTarget scalemode is used if theTarget is an Object else vbPixels if theTarget is an hDC ' Centered: If True, rendered image is centered in theTarget, offset by destX and/or destY ' If theTarget is a DC, then Centered is ignored. You must pass the correct destX,destY values ' ZoomFactor: Scaling option. Values>1 zoom out and Values<1||>0 zoom in ' Tip: To stretch image to a picturebox dimensions, pass destWidth & destHeight ' as the picturebox's scalewidth & scaleheight respectively and ZoomFactor of 1 If thePic Is Nothing Then Exit Function ' sanity checks first If thePic.Handle = 0& Then Exit Function If ZoomFactor <= 0! Then Exit Function Dim Width As Single, Height As Single, destDC As Long ' the stdPicture.Render method requires vbPixels for destination and vbHimetrics for source Width = ScaleX(thePic.Width, vbHimetric, vbPixels) ' image size in pixels Height = ScaleY(thePic.Height, vbHimetric, vbPixels) On Error Resume Next If IsObject(theTarget) Then ' passed object? If so, set scalemode if needed If theTarget Is Nothing Then Exit Function If ParamScaleMode = vbUser Then ParamScaleMode = theTarget.ScaleMode destDC = theTarget.hDC ElseIf IsNumeric(theTarget) Then ' passed hDC? If so, set scalemode if needed If ParamScaleMode = vbUser Then ParamScaleMode = vbPixels destDC = Val(theTarget) Centered = False ' only applicable if theTarget is a VB object Else Exit Function ' unhandled; abort End If If Err Then ' checks above generated an error; probably passing object without scalemode property? Err.Clear Exit Function End If If destWidth Then ' calculate destination width in pixels from ParamScaleMode destWidth = ScaleX(destWidth, ParamScaleMode, vbPixels) * ZoomFactor Else destWidth = Width * ZoomFactor End If If destHeight Then 'calculate destination height in pixels from ParamScaleMode destHeight = ScaleY(destHeight, ParamScaleMode, vbPixels) * ZoomFactor Else destHeight = Height * ZoomFactor End If ' get destX,destY in pixels from ParamScaleMode If destX Then destX = ScaleX(destX, ParamScaleMode, vbPixels) If destY Then destY = ScaleY(destY, ParamScaleMode, vbPixels) If Centered Then ' Offset destX,destY if centering destX = (ScaleX(theTarget.ScaleWidth, theTarget.ScaleMode, vbPixels) - destWidth) / 2 + destX destY = (ScaleY(theTarget.ScaleHeight, theTarget.ScaleMode, vbPixels) - destHeight) / 2 + destY End If ' setup source coords/bounds and convert to vbHimetrics If srcX Then srcX = ScaleX(srcX, ParamScaleMode, vbHimetric) If srcY Then srcY = ScaleY(srcY, ParamScaleMode, vbHimetric) If srcWidth Then srcWidth = ScaleX(srcWidth, ParamScaleMode, vbHimetric) Else srcWidth = thePic.Width If srcHeight Then srcHeight = ScaleY(srcHeight, ParamScaleMode, vbHimetric) Else srcHeight = thePic.Height If Err Then ' passed bad parameters or Err.Clear ' passed object that has no ScaleMode property (i.e., VB Frame) Else With thePic ' render, the (destDC) below and variables declared as Single needed, else type mismatch errors occur .Render (destDC), destX, destY, destWidth, destHeight, _ srcX, .Height - srcY, srcWidth, -srcHeight, ByVal 0& End With ' return success/failure If Err Then Err.Clear Else RenderStdPicture = True End If On Error GoTo 0 End Function
Edited: Short version, no resizing, scaling, positioning, or any other options. Just draw picture at 0,0 coordinates on any DC
Code:
' destDC can be any DC
Dim thePic As stdPicture
Set thePic = LoadPicture("C:\Images\Screenshots\image1002.jpg")
With thePic
.Render (destDC), 0&, 0&, ScaleX(.Width, vbHimetric, vbPixels), ScaleY(.Height, vbHimetric, vbPixels), _
0&, .Height, .Width, -.Height, ByVal 0&
End With
Edited: Pointed out in post #8 below, we should use Single vartypes for our variables we plan on passing to .Render
Last edited by LaVolpe; Dec 28th, 2014 at 11:56 PM.
Reason: updated comments/sample code
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
|