冒险解谜游戏中文网 ChinaAVG

标题: 【汉化资料】VC实现屏幕上图像比对 [打印本页]

作者: shane007    时间: 2009-5-24 17:55
标题: 【汉化资料】VC实现屏幕上图像比对
原文/ `7 L6 p1 A4 X3 z0 T% @4 E
http://tech.techweb.com.cn/redir ... 4&goto=lastpost' A: x- U# s' ]' g; H3 k4 r
4 v+ t7 b# D7 d  p1 j1 u! E

% K: I* o/ a% d" k我现在的情况是学会用VC和MFC没有多久,也大致看过Windows图形基础(包括GDI结构和一些绘制函数),有过Win32 SDK开发经历,来这里请教下大家关于如何进行屏幕上图像比对的原理和具体的方法,我总结了一下基本就是以下两个方面的问题。
6 p3 i, D. L; r
& V8 m8 Z, }. o第一种情况是要对屏幕上某个区域进行截图,得到图像后再和事先存在本地的一个图象数据比较,当然肯定事先存放的这个图象和屏幕上取得的这个图像,大小,内容这些都是完全一致的,问下这个实现原理是怎么样的,实现过程的话,是把屏幕上获得的内存数据保存为图片文件再和本地的图片文件比较好?还是把本地的图片文件加载到内存中去和屏幕上取的内存数据进行比较好?
- m6 U2 a: [; Q  @( m+ u; _
, w% f8 S4 `/ K2 d2 Y* F( s2 z第二种情况,针对屏幕上的某些图像比如前景是数字,样式颜色等都是固定不变的,但是图象背景有可能是动态变化的,这样的情况又应该怎样进行比对了?
+ J( j# B( _* v; _2 l1 w2 D/ r
; u4 i* f) e  J- h先在这里谢谢来回复提供帮忙的朋友了,提供实现原理,具体实现代码和相关资料的都非常感谢。
) L( N2 h1 L0 e( a7 o0 C' {5 s  @8 L! e) u
收藏 分享 评分 6 ]/ s1 f+ T* G* ~7 H6 A# n

; V1 q1 V8 C; X5 C* R' R% H 回复 引用 订阅 TOP + X; W6 s& C8 _6 a2 ]6 [3 k$ c
0 e! @3 x% F2 J* U% u
  
1 m# e: s+ U& c3 y7 `
0 y; y- ]3 T3 @# Ixiaojj 发短消息 & k' G+ Y" w& r. K- x3 n
加为好友
1 C. ]4 z; b+ |1 l2 ?9 Qxiaojj 当前离线 6 E# X6 ?/ x0 o3 r9 z9 S+ P6 I
0 J0 t0 w! p7 S( ?: m* J
UID168050 帖子157 精华34 积分703 阅读权限50 在线时间13 小时 注册时间2009-4-27 最后登录2009-5-22  
( @9 v# E, B2 r9 t4 s2 nTW高级会员
( g/ _+ j4 F4 v1 F! A0 K5 z2 B5 W0 t( F7 E. _& {& ^: o

% g; a8 D% z7 @- S% i& i 2#
" j% F1 `+ v1 F2 j9 ] 发表于 2009-5-5 10:47 | 只看该作者 不好意思,对不住大家了,按发帖太快了
# R4 T; G2 k7 e2 [: t
0 n* y" p! j$ `, g' r 回复 引用 TOP . n7 H# s- |' G5 Q2 B+ t8 T
, @9 b4 z* j  A
  6 z$ g% L7 {3 g$ p9 \/ o2 D
' w; D3 K& V; I2 N
xiaojj 发短消息 + H3 n4 K- I2 \1 m
加为好友
5 E0 P& }' [; p7 m3 cxiaojj 当前离线
) B3 H6 U8 l( u* Y
' u, I# V/ c4 K- R, nUID168050 帖子157 精华34 积分703 阅读权限50 在线时间13 小时 注册时间2009-4-27 最后登录2009-5-22  
% w& l* T, o9 |" J* X1 w8 p* o# {; DTW高级会员  u% S$ J( N* j6 w2 y) O+ c' Y
; U7 |5 ?; C1 r7 a

& {& P* U, g9 g4 F8 P 3#
; ~3 j& Y7 ^$ S* z 发表于 2009-5-5 10:47 | 只看该作者 希望大家指教,有熟悉这个朋友麻烦回复下吧,谢谢。 / L. G$ Y7 [  n9 `) d" \
& \2 G9 e. H% T4 V9 g
回复 引用 TOP
( K5 z. `+ a/ q7 g4 V! B/ C$ x 1 R8 y, E& w" a, w+ z
  4 c5 j- J0 b+ U- n; C" l8 y$ r" p* J
1 @1 z! T7 g* R6 r. U* x5 U
游客  4#
. A' Y- ]6 F& w' E: Q0 c 你想要得到什么形式的对比结果?
, n) A# p* [( S+ S6 b 7 ^1 b" c* z) A2 R9 t2 e' V
回复 引用 TOP
* o* M/ |+ P5 v4 y; ~3 k$ R
! F" `. b$ j( r  9 |' s+ b/ @3 R+ P0 k0 \
; |% W- I% v& P' E/ f$ Q
xiaojj 发短消息 % c9 ~9 ^  }7 V7 j1 {4 f8 ^
加为好友
! S; K+ x( q: `2 R: J8 \xiaojj 当前离线
) i, l* U6 a1 d$ W2 h+ |4 p7 }5 ]+ E% B/ r7 ]" h. X
UID168050 帖子157 精华34 积分703 阅读权限50 在线时间13 小时 注册时间2009-4-27 最后登录2009-5-22  " E: g& R% w( ~" X) A
TW高级会员
5 |7 M! `  S4 f' R% J$ P) a/ N/ P! @4 b6 }$ ~8 X

, l: r* F# G7 Z7 A3 m: T 5# , f! C6 r5 m, W4 b0 I! O2 w
发表于 2009-5-5 10:48 | 只看该作者 打个比方,就是比如我将屏幕的某个区域先截图下来,然后屏幕在没有任何变化情况下,取同样的区域图像和这个事先截好的图比较,一致就行了。反过来说,如果第一次截图的时候光标不在这个区域中,然后第二次做比对的时候,正好光标移动到过这个区域中,这就叫不一致了。
  }7 V5 G3 `) {6 M( d1 O% q. X5 U9 ]; W5 b) `* \5 s' O. q$ h( N
8 ^: d3 T1 l  k: U不知道大家理解到没有,谢谢大家回复。
3 O/ Q4 @3 ?# x3 h9 I( S& j
+ T+ |6 e0 F$ x  B 回复 引用 TOP 9 Z; O8 S' |6 ]2 G2 L2 r

6 Y  j" `' O, y, p7 B  
1 `  S; D% g1 V  D: S* @( |
. }: t' P4 v- Y! l' }$ u) N. s游客  6#
" f3 [- h: t! i# a BitBlt()函数有位图异或功能  8 p5 [4 G8 v4 A" _, {/ U) s; V- F
将一个位图用BitBlt的异或方式画到另一个位图上,结果就是异或的。如果两幅图像是完全一样的,异或出来则是一个空的BYTE数组,图标被使用BYTE的数组方式进行比较
3 Q& |7 x9 d# M0 c5 [. t8 Z7 r" \' [" j2 R. d- F
: M' V7 S4 }) ?! |8 ?2 f1 |
C/C++ code0 y$ H' r4 F: ^% X. k( x
          BYTE   *lpDib;   
1 M5 X+ z+ d- V) s          BYTE   *lpBase;            
- `: N9 {0 m( K  G$ U2 W! x6 e* Z          BITMAPINFOHEADER   bi;           * S- H8 y) N: p. e
          DWORD     dwLen;   
+ h5 w  x& m  O          DibInfo   (Orghdib,   &bi);   
- `1 z1 B; z$ i# m          dwLen       =   GlobalSize   (Orghdib);   
3 I7 E, X' I4 |2 {( D  lpDib       =   (BYTE   *)GlobalLock(Orghdib);   * Y* O% ?- F+ F) ~1 B# t* k
          lpDib     +=   (DWORD)bi.biSize   +   PaletteSize((LPSTR)&bi);   . X% D# h& O# {0 \' z1 K7 c* t
  lpBase     =   (BYTE   *)GlobalLock   (Tarhdib);   7 K: B7 F& ~: y: z3 {
          lpBase   +=   (DWORD)bi.biSize   +   PaletteSize((LPSTR)&bi);   
8 U0 s8 s2 J7 ~7 X. w; ?& h! ^  dwLen       =   dwLen   -   bi.biSize   -   PaletteSize((LPSTR)&bi);   
. _3 _8 P5 L2 Q: e; a& J0 ^          while   (dwLen--)     
( Y/ O3 N9 b& Z2 O4 X  {/*     U6 [7 h4 p0 K' U# V# C
          if(   *lpDib   >=   (int)(debasehow*(*lpBase))   )   
0 C" f  m, i2 z$ ?          *lpDib   -=   (int)(debasehow*(*lpBase));   
, N3 Y6 c' @8 F' Q          else   5 f# O: `; `- m, B' y$ N
          *lpDib   =   0; */   
5 k1 i7 c, |. S+ c6 F# l$ p  在本处加入异或操作:   *lpDig   ^=   lpBase;   ) K0 x5 x$ M! h1 b; v0 E
          lpDib   ++;   
6 N; a& }9 d& y          lpBase   ++;   
8 W9 V% d( O' }4 q  G5 v          }   3 x' P3 n. _) I
          GlobalUnlock   (Orghdib);   
: v0 H& N9 ~! Q! Y$ Q+ c          GlobalUnlock   (Tarhdib);   6 W( J/ D. P$ X/ A- |* A% l, M

/ i& u3 h, R7 t4 w6 {6 s. Y* S
' ^" M* R2 F& y  F3 d0 ^
9 B" {+ r+ f' {( G$ v+ U$ `6 A
5 @3 I; |/ c# X) F* J最后看lpDig的值就行了
9 b, E6 p; v: a# o6 f$ b' s3 X
4 q7 U* ^# |5 Y1 L! g$ B7 V 回复 引用 TOP 6 y, H4 Y0 n$ t7 k9 L# F: Z0 Q$ q
4 {1 [; r, K3 N1 J. R
  
' h9 O- {  f2 B( x2 j. L9 i# }4 y! z4 Z8 P  S% C/ j6 j0 X
游客  7#
0 D; d2 s$ i: }& s 说到鼠标光标,我记得利用桌面DC是无法获取到的。不过可以用取巧的方法得到。 + e: Y+ w& c; G3 }
5 ?' [# J" o6 X) D5 G
回复 引用 TOP
0 p. i# N9 \$ X# y, K # }( W! t7 |! y! [7 n
  
# C. e! p" }" j* {' h; L% f
# {( ~5 r1 ?( j. {游客  8#
% E! K+ Y, N$ b9 g0 ` 感谢6楼说了第一种情况的方法,我再去查查资料看看,另外现在第二种情况比较用什么方法了?就是屏幕中某个区域会显示文字,文字的颜色是固定的,但是文字背景图像是不固定的,这种情况只需要比对事先截的图像和现在屏幕中的区域图像大小一致,然后文字一致就可以,不用比较背景,该怎么做了? / D! \" w6 n. i* }) a+ A
5 Q8 Y/ f6 P$ w' V
回复 引用 TOP   z4 T/ m1 D) W/ {6 i

3 f7 G- |3 }% q9 ?, g  
* C5 u* _4 `0 h- f! \1 I3 i8 _
2 l6 w+ F; u" X8 F7 N2 T0 ]3 N, u游客  9# # j& C/ X' _; o& f! T
没有好办法,只能先在固定的区域把文字颜色的像素点抠出来,然后再记录、比对。 $ F1 O: Z) V6 I! L) ~+ O8 ~  p
4 p9 i2 m- p1 y- k- D8 T/ v6 n
回复 引用 TOP 8 r- d& ^# K) o! R4 T; o
; J" h! ?, P0 W  T
  9 M' u9 G' C' v0 Z
1 B' k, P3 I7 F
游客  10# 9 l. u  e6 K3 C  p1 S! O
如果只是要判断图象是否相同,在截取图象之后,取得像素数据,然后用memcmp比较就行了。 0 \( `7 `  \! G4 j3 F  E1 d
# K4 o. W) m0 h- M2 f9 z( M
回复 引用 TOP




欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://chinaavg.com/) Powered by Discuz! X3.2