将Picture的图像转成一数组(RGB888,RGB565)
解决方案 »
- 求解一个VB的程序代码 、急、急、急
- MsHFlexGrid能直接打印么?
- 关于vb+水晶报表9打包的问题(高分求救!)
- 如何实现不同数据库之间的数据表复制!成功马上给分!
- toolbar控件求教!!!
- 请用vb写过大型程序高手请进,有关效率问题。(看用pb写程序后感)(20:00-24:00在线)
- zmcpu(CPU),谢谢你的回答,接分 !如何使VB的程序,自己生成 .exe 文件???有难度吧~!高手!!!求助!(visualbasic2000)
- delphi翻译为VB碰到难题
- 我的程序在打包后安装,最后再更新系统时,出错"msado250.tlb无法注册",请问谁知道,帮忙回答一下
- 新生求教,命令按钮单击--显示图片框图片--如何写代码
- 高手帮帮菜鸟
- 等着要!如何用程序控制小键盘上面的3个灯的行为?
Public 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
Public 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 GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function SetDIBits Lib "gdi32" (ByVal hdc As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Public Const SRCCOPY = &HCC0020
Private Const BI_RGB = 0&
Private Const DIB_RGB_COLORS = 0&
Private Const LR_LOADFROMFILE = &H10
Private Const IMAGE_BITMAP = 0&Private iDATA() As Byte '保留位图信息
Private bDATA() As Byte '备份位图信息
Private cdata() As Byte
Private edata() As Byte
Private PicInfo As BITMAP '定义位图信息结构
Private DIBInfo As BITMAPINFO 'Device Ind. Bitmap info structure
Private mProgress As Long '% 操作进程
Private Speed(0 To 765) As Long '处理参数
Private dred(0 To 255), dgreen(0 To 255), dblue(0 To 255), dgray(0 To 255) As Long
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End TypeType BITMAPINFOHEADER '40 bytes
biSize As Long 'BITMAPINFOHEADER结构的大小
biWidth As Long
biHeight As Long
biPlanes As Integer '设备的为平面数,现在都是1
biBitCount As Integer '图像的颜色位图
biCompression As Long '压缩方式
biSizeImage As Long '实际的位图数据所占字节
biXPelsPerMeter As Long '目标设备的水平分辨率
biYPelsPerMeter As Long '目标设备的垂直分辨率
biClrUsed As Long '使用的颜色数
biClrImportant As Long '重要的颜色数。如果该项为0,表示所有颜色都是重要的
End Type
Type RGBQUAD ' 只有bibitcount为1,2,4时才有调色板
rgbBlue As Byte '蓝色分量
rgbGreen As Byte '绿色分量
rgbRed As Byte '红色分量
rgbReserved As Byte '保留值
End TypeType BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As RGBQUAD
End Type
Public Enum iFilterG '自定义的枚举常量
igray=1 '彩色转灰度
iaddnoise=2 '添加噪音
idiaoke=3 '雕刻效果 等等
End Enum
Public Sub FilterG(ByVal Filtro As iFilterG, ByVal pic As Long, ByVal factor As Long, ByRef pprogress As Long)
Dim hdcNew As Long
Dim oldhand As Long
Dim ret As Long
Dim BytesPerScanLine As Long '一个扫描行的长度
Dim PadBytesPerScanLine As Long
If WorkFilterG = True Then Exit Sub
WorkFilterG = True
On Error GoTo FilterError:
'get data buffer
Call GetObject(pic, Len(PicInfo), PicInfo) '取得对指定对象进行说明的一个结构,hobject为位图,刷子等的句柄,
'count欲取回的字节数。通常是由lpObject定义的那个结构的长度
hdcNew = CreateCompatibleDC(0&) '创建一个与屏幕兼容的设备场景
oldhand = SelectObject(hdcNew, pic)
With DIBInfo.bmiHeader
.biSize = 40 'bmp3.0
.biWidth = PicInfo.bmWidth
.biHeight = -PicInfo.bmHeight '从下往上扫描
.biPlanes = 1
.biBitCount = 32 '32位位图,默认情况下Windows不会处理最高8位,可以将它作为自己的Alpha通道
.biCompression = BI_RGB '无压缩
BytesPerScanLine = ((((.biWidth * .biBitCount) + 31) \ 32) * 4) '一个扫描行的长度,是4的倍数。
PadBytesPerScanLine = _
BytesPerScanLine - (((.biWidth * .biBitCount) + 7) \ 8)
.biSizeImage = BytesPerScanLine * Abs(.biHeight)
End With 'redimension (BGR+pad,x,y)
ReDim iDATA(1 To 4, 1 To PicInfo.bmWidth, 1 To PicInfo.bmHeight) As Byte
ReDim bDATA(1 To 4, 1 To PicInfo.bmWidth, 1 To PicInfo.bmHeight) As Byte 'get bytes
ret = GetDIBits(hdcNew, pic, 0, PicInfo.bmHeight, iDATA(1, 1, 1), DIBInfo, DIB_RGB_COLORS)
'将来自一幅位图的二进制位复制到一幅与设备无关的位图里
' 该函数利用申请到的内存,由GDI位图得到DIB位图数据,可以对DIB的格式进行控制,通过该函数,
'可以制定颜色的位数,而且可以指定是否进行压缩。如果采用了压缩方式,则必须调用该函数两次,
'一次为了得到所需内存,另外一次为了得到位图数据
'定义了与设备有关位图hBitmap的配置信息的一个设备场景的句柄
'hbmp 源位图的句柄
'uStartScan为欲复制到dib中的第一条扫描线的位置
'cScanLines欲复制的扫描先的数量
'ipvbits 指向一个缓冲区的指针
'指向BITMAPINF,对DIB的格式及颜色进行说明的一个结构。
'颜色表包含了RGB颜色
'idata(1,x,y)表示b的颜色
ret = GetDIBits(hdcNew, pic, 0, PicInfo.bmHeight, bDATA(1, 1, 1), DIBInfo, DIB_RGB_COLORS)Select Case Filtro
case igray: call gray(pprogress)
case iaddnoise: call smooth(pprogress,factor)
case idiaoke: call diaoke(pprogress)
End Select
'将数组传递给设备
ret = SetDIBits(hdcNew, pic, 0, PicInfo.bmHeight, iDATA(1, 1, 1), DIBInfo, DIB_RGB_COLORS)
'将来自与设备无关位图的二进制位复制到一幅与设备有关的位图里SelectObject hdcNew, oldhand
DeleteDC hdcNew
ReDim iDATA(1 To 4, 1 To 2, 1 To 2) As Byte
ReDim bDATA(1 To 4, 1 To 2, 1 To 2) As Byte
WorkFilterG = False
Exit Sub
FilterError:
MsgBox "Filter Error"
WorkFilterG = False
End Sub
Dim x As Long, y As Long
mProgress = 0
For y = 1 To PicInfo.bmHeight
For x = 1 To PicInfo.bmWidth
B = iDATA(1, x, y)
G = iDATA(2, x, y)
R = iDATA(3, x, y)
rgb1 = (R + G + B) / 3
iDATA(1, x, y) = rgb1
iDATA(2, x, y) = rgb1
iDATA(3, x, y) = rgb1
Next x
mProgress = (y * 100) \ PicInfo.bmHeight
pprogress = mProgress
DoEvents
Next y
pprogress = 100
DoEvents
End SubPrivate Sub addnoise(ByRef pprogress As Long, ByVal factor As Long)
Dim x As Long, y As Long
Dim R As Long, G As Long, B As Long
Dim V As Long
mProgress = 0
For y = 1 To PicInfo.bmHeight
For x = 1 To PicInfo.bmWidth
B = CLng(bDATA(1, x, y)) + ((factor * 2 + 1) * Rnd - factor)
G = CLng(bDATA(2, x, y)) + ((factor * 2 + 1) * Rnd - factor)
R = CLng(bDATA(3, x, y)) + ((factor * 2 + 1) * Rnd - factor)
If R > 255 Then R = 255
If R < 0 Then R = 0
If G > 255 Then G = 255
If G < 0 Then G = 0
If B > 255 Then B = 255
If B < 0 Then B = 0
iDATA(1, x, y) = B
iDATA(2, x, y) = G
iDATA(3, x, y) = R
Next x
mProgress = (y * 100) \ PicInfo.bmHeight
pprogress = mProgress
DoEvents
Next y
pprogress = 100
DoEvents
End SubPrivate Sub diaoke(ByRef pprogress As Long)
Dim x As Long, y As Long
Dim R As Long, G As Long, B As Long
mProgress = 0
For y = 2 To PicInfo.bmHeight - 1
For x = 2 To PicInfo.bmWidth - 1
B = 2 * CLng(bDATA(1, x - 1, y - 1)) + CLng(bDATA(1, x - 1, y)) + _
CLng(bDATA(1, x, y - 1)) - CLng(bDATA(1, x, y + 1)) - _
CLng(bDATA(1, x + 1, y)) - 2 * CLng(bDATA(1, x + 1, y + 1))
G = 2 * CLng(bDATA(2, x - 1, y - 1)) + CLng(bDATA(2, x - 1, y)) + _
CLng(bDATA(2, x, y - 1)) - CLng(bDATA(2, x, y + 1)) - _
CLng(bDATA(2, x + 1, y)) - 2 * CLng(bDATA(2, x + 1, y + 1))
R = 2 * CLng(bDATA(3, x - 1, y - 1)) + CLng(bDATA(3, x - 1, y)) + _
CLng(bDATA(3, x, y - 1)) - CLng(bDATA(3, x, y + 1)) - _
CLng(bDATA(3, x + 1, y)) - 2 * CLng(bDATA(3, x + 1, y + 1))
B = (CLng(bDATA(1, x, y)) + B) \ 2 + 50
G = (CLng(bDATA(2, x, y)) + G) \ 2 + 50
R = (CLng(bDATA(3, x, y)) + R) \ 2 + 50
If R > 255 Then R = 255
If R < 0 Then R = 0
If G > 255 Then G = 255
If G < 0 Then G = 0
If B > 255 Then B = 255
If B < 0 Then B = 0
iDATA(1, x, y) = B
iDATA(2, x, y) = G
iDATA(3, x, y) = R
Next x
mProgress = (y * 100) \ PicInfo.bmHeight
pprogress = mProgress
DoEvents
Next y
pprogress = 100
DoEvents
End Sub
Private Sub gray_Click()
Screen.MousePointer = 11
Timer1.Enabled = True
Call FilterG(igray, Picture1.Image, 0, mProgress)
Picture1.Refresh
Screen.MousePointer = 1End SubPrivate Sub addnoise_Click()
On Error Resume Next
Screen.MousePointer = 11
Timer1.Enabled = True Call FilterG(iaddnoise, Picture1.Image, InputBox("请输入噪音系数", "噪音系数", 50), mProgress)
Picture1.Refresh
Screen.MousePointer = 1
End Sub
http://community.csdn.net/Expert/topic/3252/3252001.xml?temp=.8577387关于888转565的方法:
一般是用去低位的方法比较快速,如果要考虑到前后的颜色转换失真小,则因该对每个颜色分量进行统计降序排列,取排序在前的。
比如:红色由256级(888)转换到32级(565),则应该将该图片中所有点的红色统计下来,得到一个统计值,取最多的32种红色,其他的取和前面得到的32种红色最相近的代替。
其他颜色也是如此。这样就可以得到和原来相差很小的图像了。