用 StretchBlt 处理图像有后黑边,
原图如下:处理后保存的图片如下(处理后的图片超过2M 论坛上传不了,故对图片进行了QQ截图,展示效果如下):
代码如下:
思路:以制作宽长比为: 102/152 的 的图像尺寸, picture2控件加载原始图片,获取原始图片长宽像素值, 对此原始像素值按照102/152的比例进行计算,计算出长度或者宽度上需要增补的尺寸,以达到102/152这一比例。然后将picture1控件的长宽尺寸设置为 通过计算后的目标尺寸,然后用StretchBlt 函数将picture2控件的图像 加载打 picture1控件,然后再保存picture1控件上的目标图片,即为保存到C盘的123.jpg 如源码。 奇怪的是 保存后的图片,下面有黑边,实在是不知道怎么处理了,求教各位高手!
'Form1上添加1个图片框picture1
Private Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetPixelV Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor 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 SetStretchBltMode Lib "gdi32" (ByVal hDC As Long, ByVal nStretchMode As Long) As Long
Private Declare Function GetDC Lib "user32 " (ByVal hWND As Long) As Long
Private Const HALFTONE = 4
Private Const SRCCOPY = &HCC0020 Dim fs
Dim wScreen As Long
Dim hScreen As Long
Dim w As Long
Dim h As Long
Dim cw As Long
Dim ch As Long
Dim Dw As Long
Dim Dh As Long
Dim DifferenceH As Long
Dim DifferenceW As Long
Dim PIC As PictureBox
Dim rtn As Boolean
Dim rtm As Long
Dim Hdc1 As Long, Hdc2 As LongPrivate Sub Form_Load()
Picture2.Picture = LoadPicture("C:\1.jpg")
Printer.ScaleMode = 3
Printer.ScaleWidth = 1181
Printer.ScaleHeight = 1772
Printer.ScaleLeft = 0
Printer.ScaleTop = 0
AllPrint
End Sub
Sub AllPrint() '此函数用来对图片进行裁切打印 w = Picture2.Width
h = Picture2.Height
If w <= h Then '此判断用来打印宽带小于等等高度的图片
Printer.Orientation = 1 '打印机纵向
ch = w * 152 \ 102
cw = 102 * h \ 152
DifferenceW = w - cw
DifferenceH = h - ch
Debug.Print DifferenceW
Debug.Print DifferenceH
If DifferenceW >= 0 And DifferenceH <= 0 Then
Picture1.Width = w
Picture1.Height = ch
Call SetStretchBltMode(Picture1.hDC, HALFTONE)
rtm = StretchBlt(Picture1.hDC, 0, Abs(DifferenceH / 2), w, ch, Picture2.hDC, 0, 0, w, ch, vbSrcCopy)
Picture1.Refresh
SavePicture Picture1.Image, "c:\123.jpg "
End If
End If
End Sub
原图如下:处理后保存的图片如下(处理后的图片超过2M 论坛上传不了,故对图片进行了QQ截图,展示效果如下):
代码如下:
思路:以制作宽长比为: 102/152 的 的图像尺寸, picture2控件加载原始图片,获取原始图片长宽像素值, 对此原始像素值按照102/152的比例进行计算,计算出长度或者宽度上需要增补的尺寸,以达到102/152这一比例。然后将picture1控件的长宽尺寸设置为 通过计算后的目标尺寸,然后用StretchBlt 函数将picture2控件的图像 加载打 picture1控件,然后再保存picture1控件上的目标图片,即为保存到C盘的123.jpg 如源码。 奇怪的是 保存后的图片,下面有黑边,实在是不知道怎么处理了,求教各位高手!
'Form1上添加1个图片框picture1
Private Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function SetPixelV Lib "gdi32" (ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal crColor 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 SetStretchBltMode Lib "gdi32" (ByVal hDC As Long, ByVal nStretchMode As Long) As Long
Private Declare Function GetDC Lib "user32 " (ByVal hWND As Long) As Long
Private Const HALFTONE = 4
Private Const SRCCOPY = &HCC0020 Dim fs
Dim wScreen As Long
Dim hScreen As Long
Dim w As Long
Dim h As Long
Dim cw As Long
Dim ch As Long
Dim Dw As Long
Dim Dh As Long
Dim DifferenceH As Long
Dim DifferenceW As Long
Dim PIC As PictureBox
Dim rtn As Boolean
Dim rtm As Long
Dim Hdc1 As Long, Hdc2 As LongPrivate Sub Form_Load()
Picture2.Picture = LoadPicture("C:\1.jpg")
Printer.ScaleMode = 3
Printer.ScaleWidth = 1181
Printer.ScaleHeight = 1772
Printer.ScaleLeft = 0
Printer.ScaleTop = 0
AllPrint
End Sub
Sub AllPrint() '此函数用来对图片进行裁切打印 w = Picture2.Width
h = Picture2.Height
If w <= h Then '此判断用来打印宽带小于等等高度的图片
Printer.Orientation = 1 '打印机纵向
ch = w * 152 \ 102
cw = 102 * h \ 152
DifferenceW = w - cw
DifferenceH = h - ch
Debug.Print DifferenceW
Debug.Print DifferenceH
If DifferenceW >= 0 And DifferenceH <= 0 Then
Picture1.Width = w
Picture1.Height = ch
Call SetStretchBltMode(Picture1.hDC, HALFTONE)
rtm = StretchBlt(Picture1.hDC, 0, Abs(DifferenceH / 2), w, ch, Picture2.hDC, 0, 0, w, ch, vbSrcCopy)
Picture1.Refresh
SavePicture Picture1.Image, "c:\123.jpg "
End If
End If
End Sub
在设计窗口时,对 PictureBox 的几个属性进行如下设置(在 Form_Load()开头加代码也可):
Picture1.Appearance = 0
Picture1.BorderStyle = 0
Picture1.AutoRedraw = True
Picture2.AutoSize = True图片缩放代码:
Sub AllPrint()
w = Picture2.ScaleWidth
h = Picture2.ScaleHeight
If w <= h Then
ch = w * 152 / 102
cw = h * 102 / 152
' 这是原始高度不变,调整宽度适应比例
Picture1.Width = cw
Picture1.Height = h
Picture1.PaintPicture Picture2.Image, 0, 0, cw, h, 0, 0, w, h, vbSrcCopy
' 下面这个是宽度不变,调整高度来适应比例
'Picture1.Width = w
'Picture1.Height = ch
'Picture1.PaintPicture Picture2.Image, 0, 0, w, ch, 0, 0, w, h, vbSrcCopy
SavePicture Picture1.Image, "E:\Temp\123.bmp"
End If
End Sub
SavePicture 保存的格式是Bmp的。
你把扩展名写成 .jpg 并没有实际作用,如果要保存jpg格式图片文件,可以在网上搜索一下代码。
如果 PictureBox 被遮住(全部,或部分),往往会出现类似“花屏”的结果。
'假定原始图片 1000 * 1000'
w = 1000
h = 1000 ch = w * 152 \ 102
cw = 102 * h \ 152 DifferenceW = w - cw
DifferenceH = h - ch 'StretchBlt(Picture1.hDC, 0, Abs(DifferenceH / 2), w, ch, Picture2.hDC, 0, 0, w, ch, vbSrcCopy)'
Debug.Print "目标", 0, Abs(DifferenceH / 2), w, ch
Debug.Print "源", 0, 0, w, ch
End Sub
目标 0 245 1000 1490
源 0 0 1000 1490
你从 1000*1000 上切 1000*1490,下面的 490 有什么内容?
@ Chen8013 ,你的回答是通过图片缩放 我试了你的代码 图片会有压缩或者拉伸,造成了失真@ Tiger_Zhao ,你的回答虽然没解决问题,但是却提醒了哦,对于 'Picture1.PaintPicture Picture2.Image, 0, 0, w, ch, 0, 0, w, h, vbSrcCopy
StretchBlt(Picture1.hDC, 0, Abs(DifferenceH / 2), w, ch, Picture2.hDC, 0, 0, w, ch, vbSrcCopy) paintpicture 和 stretchebit 这两个函数 里面主要的八个参数 我的理解有误,所以造成了黑边问题。
可恨的是 我对这两个函数里面的参数所代表的意义,一字一句的读了不下10遍,还是没理解对,这次算是理解了!!!
如下图 ,已经可以得到想要的图片了!
使用 PaintPicture 方法,可以在窗体、图片框和 Printer 对象上的任何地方,绘制图形。PaintPicture 方法的语法是:[object.]PaintPicture pic, destX, destY[, destWidth[, destHeight[, srcX _[, srcY[, srcWidth[, srcHeight[, Op]]]]]]]目标 object 指的是窗体、图片框或 Printer 对象,这些地方都是 pic 图片表现的处所。如果 object 被忽略了,则认为指定的就是当前的窗体。pic 参数必须是一个图片对象,它是由窗体或控件的 Picture 属性决定。destX 和 destY 参数,是按照 objec 的 ScaleMode,该图象将出现的水平和垂直位置。destWidth 和 destHeight 参数是可选项,用来设置在 object 目标中该图象的宽度和高度。srcX 和 srcY 参数是可选项,用来定义 pic 中裁剪区左上角的 x 和 y 坐标。可选的 Op 参数用来定义当在目标 object 上绘图时,在图片上执行的光栅操作(例如,AND 和 XOR)。PaintPicture 方法可代替 BitBlt Windows API 函数,在将矩形图形块从一个地方移到任意另一地方时,它可执行广泛的各种操作。例如,可以使用 PaintPicture 方法生成同一位图的多份副本,并将它们平铺在窗体上。使用这种方法,比在窗体上移动图片控件要快。下列代码是用来平铺图片控件的 100 份拷贝,并且通过给 destWidth 设置一个负值,可以使每张图片进行水平翻转。For i = 0 To 10
For j = 0 To 10
Form1.PaintPicture picF.Picture, j * _
picF.Width, i * picF.Height, _
picF.Width, -picF.Height
Next j, i详细信息 请参阅《语言参考》的“PaintPicture 方法”。
object.PaintPicturepicture, x1, y1, width1, height1, x2, y2, width2, height2, opcode
我没理解你的目的是“留白”来实现等比缩放。
当然如果用PaintPicture实现也是可以的。
如果你要实现“留白”部分真正的为白色,应该明确指定Picture1的BackColor为白色。
否则,留白部分有可能是黑色,或者为系统的“窗口背景”或“按钮表面”的颜色,不一定是白色。