StretchBlt - Picture Stretching
April 30, 2008
The StretchBlt function copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if necessary. Windows stretches or compresses the bitmap according to the stretching mode currently set in the destination device context.
Declare Function StretchBlt Lib “gdi32″ Alias “StretchBlt” (ByVal hdc 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 nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Parameter Information of StretchBlt
· hdcDest
Identifies the destination device context.
· nXOriginDest
Specifies the x-coordinate, in logical units, of the upper-left corner of the destination rectangle.
· nYOriginDest
Specifies the y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
· nWidthDest
Specifies the width, in logical units, of the destination rectangle.
· nHeightDest
Specifies the height, in logical units, of the destination rectangle.
· hdcSrc
Identifies the source device context.
· nXOriginSrc
Specifies the x-coordinate, in logical units, of the upper-left corner of the source rectangle.
· nYOriginSrc
Specifies the y-coordinate, in logical units, of the upper-left corner of the source rectangle.
· nWidthSrc
Specifies the width, in logical units, of the source rectangle.
· nHeightSrc
Specifies the height, in logical units, of the source rectangle.
· dwRop
Specifies the raster operation to be performed. Raster operation codes define how Windows combines colors in output operations that involve a brush, a source bitmap, and a destination bitmap.
REM This project needs two picture boxes a button
Private Type POINTAPI
X As Long
Y As Long
End Type
Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long,_
ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long,_
ByVal X As Long,ByVal Y As Long, ByVal crColor As Long) As Long
Private Declare Function PaintDesktop Lib "user32" (ByVal hdc As Long) _
As Long
Private Declare Function StretchBlt Lib "gdi32" (ByVal hdc 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 nSrcWidth As Long, ByVal nSrcHeight As Long, ByVal dwRop As Long)_
As Long
Private Declare Function GetBkColor Lib "gdi32" (ByVal hdc As Long)_
As Long
Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long,_
ByVal X As Long, ByVal Y As Long, lpPoint As POINTAPI) As Long
Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long,_
ByVal X As Long, ByVal Y As Long) As Long
Const ScrCopy = &HCC0020
Const Yellow = &HFFFF&
Private Sub Form_Load()
Dim Cnt1 As Byte, Cnt2 As Byte, Point As POINTAPI
Me.AutoRedraw = True
Me.ScaleMode = vbPixels
Picture1.ScaleMode = vbPixels
Picture2.ScaleMode = vbPixels
Picture1.BorderStyle = 0: Picture2.BorderStyle = 0
Command1.Caption = "Paint && Stretch"
Picture1.AutoRedraw = False
Picture2.AutoRedraw = False
For Cnt1 = 0 To 100 Step 3
For Cnt2 = 0 To 100 Step 3
Point.X = Cnt1: Point.Y = Cnt2
MoveToEx Me.hdc, Cnt1, Cnt2, Point
LineTo Me.hdc, 200, 200
Next Cnt2
Next Cnt1
For Cnt1 = 0 To 100 Step 5
For Cnt2 = 0 To 100 Step 5
SetPixel Me.hdc, Cnt1, Cnt2, Yellow
Next Cnt2
Next Cnt1
End Sub
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
Dim XX As Long, YY As Long, A As Long
XX = X: YY = Y
Picture2.BackColor = GetPixel(Picture1.hdc, XX, YY)
End Sub
Private Sub Picture1_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
If Button = 1 Then
Dim XX As Long, YY As Long, A As Long
XX = X: YY = Y
Picture2.BackColor = GetPixel(Picture1.hdc, XX, YY)
End If
End Sub
Private Sub Picture1_MouseUp(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
Dim XX As Long, YY As Long, A As Long
XX = X: YY = Y
Picture2.BackColor = GetPixel(Picture1.hdc, XX, YY)
End Sub
Private Sub Command1_Click()
Picture2.Width = 100: Picture2.Height = 100
Picture1.Width = 50: Picture1.Height = 50
Picture1.Picture = LoadPicture("")
DoEvents
PaintDesktop Picture1.hdc
StretchBlt Picture2.hdc, 0, 0, 100, 100, Picture1.hdc, 0, 0,_
50, 50, ScrCopy
End Sub
Posted in
content rss
September 7th, 2008 at 10:47 am
The ability to draw an image on the screen that is a different size than the original source image is incredibly easy with Win32’s GDI StretchBlt function and its variants. However, using StretchBlt with large images, especially with a large amount of stretch, is very slow. Also, shrinking images with StretchBlt often produces poor image quality. This article provides some simple techniques to get around the performance and image quality limitations of StretchBlt.
The most aggravating effect caused by the poor performance of StretchBlt is to make scrolling very slow. If you call StretchBlt to draw an image each time the scroll bars are moved, you may be in for a long wait. A simple solution is to only call StretchBlt when the size of the image actually needs to change. Instead of stretching each time the image is drawn to the screen, only stretch it when necessary and rely on BitBlt (which is much faster) for the majority of your drawing. The downside of this approach means storing a copy of the stretched image in memory as well as the original source image. Considering the ever-present need for speed and these times of cheap memory modules, making a copy seems very reasonable.