听说 GetPixel 比较慢,那用什么函数更快,怎么用

听说 GetPixel 比较慢,那用什么函数更快,怎么用,第1张

el相当相当的慢,呵呵,特别是你想要绘制整个图片都用SetPixel的时候,哈哈,所以,不要这样来用

解决的方法:

1。如果你能解析bmp格式,那么,创建BMP图片,然后用LoadPicture加载到Picture中显示

2。如果你会用C++,那么用C++写一个控件,用于绘图

3。用C#或VB.net吧,处理起来相当的快速。

我不是太明确你第一个问题的意思。我的理解是你要对屏幕的某个目标进行取色。问题是如何确认这个目标的位置。如果目标是固定的坐标或者在固定的屏幕比例中出现,那么直接针对的计算坐标来取色即可。但我想你希望的是对一个不固定的坐标取色。那么多半是窗口坐标,这样的话可以获取窗口的DC来取色。总的来说,你必须确立一个参照坐标。

2,出错是因为并不是所有DC都支持GetPixel 和 SetPixel。例如win7的很多窗体,Java程序的窗体。不过DirectX的窗体好像是可以的。因为这个原因,考虑到兼容性需要,我往往是使用BitBlt来对一个像素点截屏再进行取色。一般来说BitBlt 不会让效率降低太多。可能几十倍而已,几千几百个点的话可以忽略。如果你是对大范围取色,BitBlt会比GetPixel更有效率。

3.读取jpg需要使用一些解码包会比较好,因为jpg的结构相当复杂,自己写代码会非常费事,事实上,我对JPG的结构还挺熟悉,但从来不敢想象自己写一个关于他的解压包。如果你是懒得找包的话,给你一个不太好的但可以处理的办法:使用JNI(Java native interface),他可以用作java 和c之间的界面, 由jdk自带。你可以在C里调度Java。java的 ImageIO.read(File file)方程可以直接读取bmp gif jpg 和 png 文件。读出来的BufferedImage 可以直接获取像素资料,但是效率不高,你可以从BufferedImage对象中获取 WritableRaster,然后获取DataBuffer 最后是直接的 byte 或者 int 数组数据。但是,前提是你要会JNI,同时JNI在C中调度Java的代码也是非常糟糕的,代码效率还可以,但代码会极度难看。如果真的决定使用JNI,那我建议你先用Java写一个 byte[] readJPG(String path)的方程然后再C调度这个方程获取 byte 数组,而不是直接从C调用ImageIO.read(),这样会省事非常多

但还是建议找C的解码包。给代码是不可能的,我原意话10分钟来回答问题,但不太原意话1小时来写代码。而且自己寻找答案会获得和学习更多。

最后如果你想要做的是图像识别,可以说jpg图片不是很好的选择,因为那是一种会丢失数据的文件格式,你用点对点的精确识别方法肯定(99.9999%)不能识别出图片。用模糊识别是要有很好的技术知识同时效率也会降低。建议使用BMP作为识别图片。BMP的解码包和源码网上一大堆。

先截图,再提取像素

在窗体上放一个PictureBox,叫PicT,ScaleMode=3,作截屏的目标。

代码如下

------------------------------

Dim RGB() As Long

Private Const SRCCOPY = &HCC0020

Private Declare Function GetDC Lib "user32" (ByVal hWnd 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 Sub Form_Load()

PicT.Height = Screen.Height

PicT.Width = Screen.Width

End Sub

'如果需要,可以直接用这个

Private Sub GetPoints(x() As Long, y() As Long)

'截屏

StretchBlt PicT.hDC, 0, 0, Screen.Width, Screen.Height, GetDC(0), 0, 0, Screen.Width, Screen.Height, SRCCOPY

'将以x的大小为准,xy坐标应配套用

ReDim RGB(UBound(x))

Dim i As Long

For i = 0 To UBound(x)

'得到点颜色,返回的是类似rgb()的数字,好像和GetPixel一样(OLE_COLOR)

RGB(i) = PicT.Point(x(i), y(i))

Next i

End Sub

---------------------------

下面是使用示例

---------------------------

Private Sub Command1_Click()

'这一块你可以用循环进行赋值,本例取3点

Dim x(2) As Long, y(2) As Long

x(0) = 50

x(1) = 100

x(2) = 300

y(0) = 50

y(1) = 100

y(2) = 300

'赋值结束,传入参数

GetPoints x(), y()

'输出结果

MsgBox RGB(0)

MsgBox RGB(1)

MsgBox RGB(2)

End Sub

PS:我只在win7里试过,xp应该也行。

rgb这么分解:

Red = (Color Mod 256)

Green = ((Color Mod 65536) \ 256)

Blue = (Color \ 65536)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/8178809.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存