compix 0.0.5 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cb42dd67dc46a435223d649a19c74494e9f6a920
4
- data.tar.gz: 4608581180744a8fc6df686c71fdcc99df1fa673
3
+ metadata.gz: d31400ba7b637660ef09a34d8c45228d25811274
4
+ data.tar.gz: 2c5589a1b5da50cd87e2d4ad50a908168139acf7
5
5
  SHA512:
6
- metadata.gz: 5861d769b5ee93c95c6811a931dd782e7f8def8117f04162b7c9150a7255e10648e2197bf843de3bc98e31466b9d20e4b3c157dee16ee42250474ef16822ac4f
7
- data.tar.gz: a5328685d480d67477f3624b00e8a2c09648bdadf1c02f5ee0c835c2869ca0fbf5f7686e5733ae085acf6582884bcb23ca44e37bb9222629de1c677ba7a9752f
6
+ metadata.gz: 6676275970f1c794242b386f74f0fc5fd419a96800e758db97d57ce7b79741092638098a9a15a36d683d3f2ebae9d9f589ebb23ebffa0e007db491e30ea13b04
7
+ data.tar.gz: 07740fd33ca945ab6c89c7d522ff284561823b3701696a62b45c7806c2b49420e4693715f701ccb34db94cb5cc7cd1960ee2650599139e9309e68a4899a69a9f
@@ -1,146 +1,132 @@
1
- #include <ruby.h>
2
- #include <stdbool.h>
3
-
4
- // Types and macros from OilyPNG for compatibility
5
- typedef unsigned int PIXEL; // Pixels use 32 bits unsigned integers
6
- typedef unsigned char BYTE; // Bytes use 8 bits unsigned integers
7
- #define R_BYTE(pixel) ((BYTE) (((pixel) & (PIXEL) 0xff000000) >> 24))
8
- #define G_BYTE(pixel) ((BYTE) (((pixel) & (PIXEL) 0x00ff0000) >> 16))
9
- #define B_BYTE(pixel) ((BYTE) (((pixel) & (PIXEL) 0x0000ff00) >> 8))
10
- #define A_BYTE(pixel) ((BYTE) (((pixel) & (PIXEL) 0x000000ff)))
11
-
12
- void Init_compix();
13
- VALUE compix_compare_pixels(VALUE self, VALUE subimage, VALUE bigimage,
14
- VALUE minCoord, VALUE maxCoord, VALUE threshold);
15
-
16
- void Init_compix(){
17
- VALUE klass = rb_define_class("Compix", rb_cObject);
18
- rb_define_singleton_method(klass, "compare_pixels", compix_compare_pixels, 5);
19
- }
20
-
21
- int getImgWidth(VALUE img){
22
- int width = NUM2INT(rb_funcall(img, rb_intern("width"), 0));
23
- return width;
24
- }
25
-
26
- int getImgHeight(VALUE img){
27
- int height = NUM2INT(rb_funcall(img, rb_intern("height"), 0));
28
- return height;
29
- }
30
-
31
- int comparePixels(PIXEL pone, PIXEL ptwo, int threshold){
32
- unsigned char ored = R_BYTE(pone);
33
- unsigned char ogreen = G_BYTE(pone);
34
- unsigned char oblue = B_BYTE(pone);
35
- unsigned char tred = R_BYTE(ptwo);
36
- unsigned char tgreen = G_BYTE(ptwo);
37
- unsigned char tblue = B_BYTE(ptwo);
38
- if(ored - tred > threshold || tred - ored > threshold ||
39
- ogreen - tgreen > threshold || tgreen - ogreen > threshold ||
40
- oblue - tblue > threshold || tblue - oblue > threshold){
41
- return false;
42
- }
43
- return true;
44
- }
45
-
46
- int compareAt(unsigned int *pixelsSmall, unsigned int *pixelsBig, int thres, int bigXoffset, int bigYoffset,
47
- int siwidth, int siheight, int sswidth, int ssheight){
48
- PIXEL firstPixel;
49
- PIXEL secPixel;
50
- int match = 0;
51
- int unmatch = 0;
52
- int x, y;
53
- int small_image_coord;
54
- int bigCoord = 0;
55
- for(y = 0; y < siheight; y++){
56
- for(x = 0; x < siwidth; x++){
57
- small_image_coord = y * siwidth + x;
58
- firstPixel = pixelsSmall[small_image_coord];
59
- bigCoord = sswidth*(y+bigYoffset)+(x+bigXoffset);
60
- if(bigCoord >= (sswidth)*(ssheight) - 2 ){
61
- break;
62
- }
63
- secPixel = pixelsBig[bigCoord];
64
- if(comparePixels(firstPixel, secPixel, thres)){
65
- match++;
66
- }
67
- else {
68
- unmatch++;
69
- }
70
- }
71
- if(unmatch > match){
72
- break;
73
- }
74
- }
75
- return match;
76
- }
77
-
78
- VALUE compix_compare_pixels(VALUE self, VALUE subimage, VALUE bigimage,
79
- VALUE minCoord, VALUE maxCoord, VALUE threshold){
80
- VALUE pixelsf = rb_funcall(subimage, rb_intern("pixels"), 0);
81
- VALUE pixelss = rb_funcall(bigimage, rb_intern("pixels"), 0);
82
-
83
- int siwidth = getImgWidth(subimage);
84
- int siheight = getImgHeight(subimage);
85
- int sswidth = getImgWidth(bigimage);
86
- int ssheight = getImgHeight(bigimage);
87
-
88
- unsigned int *bytearray_subimg = malloc(siwidth * siheight * sizeof(unsigned int));
89
- unsigned int *bytearray_screenshot = malloc(sswidth * ssheight * sizeof(unsigned int));
90
-
91
- int thres = NUM2UINT(threshold);
92
- int match = 0;
93
- int maxmatch = 0;
94
- int maxX = -1;
95
- int maxY = -1;
96
- int xLeftLimit = NUM2INT(rb_ary_entry(minCoord, 0));
97
- int yTopLimit = NUM2INT(rb_ary_entry(minCoord, 1));
98
- int xRightLimit = NUM2INT(rb_ary_entry(maxCoord, 0));
99
- int yBottomLimit = NUM2INT(rb_ary_entry(maxCoord, 1));
100
- // I didn't want to break backwards compatibility, so while this is less legible
101
- // and slower if old version of compix is used, it will still work.
102
- // The third and fourth entry in the array specifies from where to start checking the big image.
103
- // Used for e.g. findAllSubImages in rubypng
104
- int xstart = 0; //NUM2INT(rb_ary_entry(minCoord, 2));
105
- int ystart = 0 ; //NUM2INT(rb_ary_entry(minCoord, 3));
106
- int x, y;
107
- int pixels = 0;
108
- int compPix = siwidth * siheight;
109
- VALUE retArr;
110
- int matchPercent;
111
-
112
- // Create bytearrays for pixels
113
- for(y = 0 ; y < siheight ; y++){
114
- for(x = 0 ; x < siwidth ; x++){
115
- bytearray_subimg[y*siwidth + x] = NUM2UINT(rb_ary_entry(pixelsf,y*siwidth + x));
116
- }
117
- }
118
- for(y = 0 ; y < ssheight ; y++){
119
- for(x = 0 ; x < sswidth ; x++){
120
- bytearray_screenshot[y*sswidth + x] = NUM2UINT(rb_ary_entry(pixelss,y*sswidth + x));
121
- }
122
- }
123
-
124
-
125
- for(y = ystart ; y < yBottomLimit-siheight; y++){
126
- for(x = xstart ; x < xRightLimit-siwidth; x++){
127
- match = compareAt(bytearray_subimg, bytearray_screenshot, thres, x, y,
128
- siwidth, siheight, sswidth, ssheight);
129
- if(match > maxmatch){
130
- maxmatch = match;
131
- maxX = x;
132
- maxY = y;
133
- }
134
- }
135
- }
136
- free(bytearray_subimg);
137
- free(bytearray_screenshot);
138
- pixels = x * ( ssheight - siheight ) + y;
139
- matchPercent = (100 * maxmatch) / compPix;
140
- retArr = rb_ary_new();
141
- rb_ary_push(retArr, INT2NUM(matchPercent));
142
- rb_ary_push(retArr, INT2NUM(maxX));
143
- rb_ary_push(retArr, INT2NUM(maxY));
144
- rb_ary_push(retArr, INT2NUM(pixels));
145
- return retArr;
146
- }
1
+ #include <ruby.h>
2
+ #include <stdbool.h>
3
+ #include <stdio.h>
4
+ #include "compix.h"
5
+
6
+ void Init_compix(){
7
+ VALUE CompixModule = rb_define_module("Compix");
8
+ rb_define_singleton_method(CompixModule, "find_subimage", find_subimage, 3);
9
+ }
10
+
11
+ bool compare_pixels(PIXEL pone, PIXEL ptwo, int threshold){
12
+ BYTE ored = R_BYTE(pone);
13
+ BYTE ogreen = G_BYTE(pone);
14
+ BYTE oblue = B_BYTE(pone);
15
+ BYTE tred = R_BYTE(ptwo);
16
+ BYTE tgreen = G_BYTE(ptwo);
17
+ BYTE tblue = B_BYTE(ptwo);
18
+ if(ored - tred > threshold || tred - ored > threshold ||
19
+ ogreen - tgreen > threshold || tgreen - ogreen > threshold ||
20
+ oblue - tblue > threshold || tblue - oblue > threshold){
21
+ return false;
22
+ }
23
+ return true;
24
+ }
25
+
26
+ int compare_at(PIXEL *pixelsSmall, PIXEL *pixelsBig, int thres, int bigXoffset, int bigYoffset,
27
+ int siwidth, int siheight, int sswidth, int ssheight){
28
+ PIXEL firstPixel;
29
+ PIXEL secPixel;
30
+ int match = 0;
31
+ int unmatch = 0;
32
+ int x, y;
33
+ int small_image_coord;
34
+ int bigCoord = 0;
35
+ for(y = 0; y < siheight; y++){
36
+ for(x = 0; x < siwidth; x++){
37
+ small_image_coord = y * siwidth + x;
38
+ firstPixel = pixelsSmall[small_image_coord];
39
+ bigCoord = sswidth*(y+bigYoffset)+(x+bigXoffset);
40
+ if(bigCoord >= (sswidth)*(ssheight) ){
41
+ break;
42
+ }
43
+ secPixel = pixelsBig[bigCoord];
44
+ if(compare_pixels(firstPixel, secPixel, thres)){
45
+ match++;
46
+ }
47
+ else {
48
+ unmatch++;
49
+ }
50
+ }
51
+ if(unmatch > match){
52
+ break;
53
+ }
54
+ }
55
+ return match;
56
+ }
57
+
58
+ PIXEL* image_to_bytearray(PIXEL *bytearray_ptr, VALUE image){
59
+ VALUE pixels = rb_funcall(image, rb_intern("pixels"), 0);
60
+ int x, y;
61
+
62
+ int width = NUM2INT(rb_funcall(image, rb_intern("width"), 0));
63
+ int height = NUM2INT(rb_funcall(image, rb_intern("height"), 0));
64
+
65
+ for(y = 0 ; y < height ; y++){
66
+ for(x = 0 ; x < width ; x++){
67
+ bytearray_ptr[y * width + x] = NUM2UINT(rb_ary_entry(pixels, y * width + x));
68
+ }
69
+ }
70
+ return bytearray_ptr;
71
+ }
72
+
73
+ VALUE find_subimage(VALUE self, VALUE subimage, VALUE bigimage, VALUE threshold){
74
+ VALUE subimage_match_obj;
75
+
76
+ int siwidth = NUM2INT(rb_funcall(subimage, rb_intern("width"), 0));
77
+ int siheight = NUM2INT(rb_funcall(subimage, rb_intern("height"), 0));
78
+ int sswidth = NUM2INT(rb_funcall(bigimage, rb_intern("width"), 0));
79
+ int ssheight = NUM2INT(rb_funcall(bigimage, rb_intern("height"), 0));
80
+
81
+ PIXEL *bytearray_subimg = malloc(siwidth * siheight * sizeof(PIXEL));
82
+ PIXEL *bytearray_big_image = malloc(sswidth * ssheight * sizeof(PIXEL));
83
+
84
+ int thres = NUM2UINT(threshold);
85
+ int match = 0;
86
+ int maxmatch = 0;
87
+ int maxX = -1;
88
+ int maxY = -1;
89
+ //int xLeftLimit = NUM2INT(rb_ary_entry(minCoord, 0));
90
+ //int yTopLimit = NUM2INT(rb_ary_entry(minCoord, 1));
91
+ //int xRightLimit = NUM2INT(rb_ary_entry(maxCoord, 0));
92
+ //int yBottomLimit = NUM2INT(rb_ary_entry(maxCoord, 1));
93
+ // I didn't want to break backwards compatibility, so while this is less legible
94
+ // and slower if old version of compix is used, it will still work.
95
+ // The third and fourth entry in the array specifies from where to start checking the big image.
96
+ // Used for e.g. findAllSubImages in rubypng
97
+ int xstart = 0; //NUM2INT(rb_ary_entry(minCoord, 2));
98
+ int ystart = 0 ; //NUM2INT(rb_ary_entry(minCoord, 3));
99
+ int x, y;
100
+ int compPix = siwidth * siheight;
101
+
102
+ // Create bytearrays for pixels
103
+ bytearray_subimg = image_to_bytearray(bytearray_subimg, subimage);
104
+ bytearray_big_image = image_to_bytearray(bytearray_big_image, bigimage);
105
+
106
+ for(y = ystart ; y <= ssheight - siheight; y++){
107
+ for(x = xstart ; x <= sswidth - siwidth; x++){
108
+ match = compare_at(bytearray_subimg, bytearray_big_image, thres, x, y,
109
+ siwidth, siheight, sswidth, ssheight);
110
+ if(match > maxmatch){
111
+ maxmatch = match;
112
+ maxX = x;
113
+ maxY = y;
114
+ }
115
+ }
116
+ }
117
+
118
+ free(bytearray_subimg);
119
+ free(bytearray_big_image);
120
+
121
+ subimage_match_obj = initialize_subimage_match_obj(maxX, maxY, compPix, maxmatch);
122
+ return subimage_match_obj;
123
+ }
124
+
125
+ VALUE initialize_subimage_match_obj(int coord_x, int coord_y, int pixels_compared, int pixels_matched){
126
+ VALUE mCompixModule = rb_const_get(rb_cObject, rb_intern("Compix"));
127
+ VALUE cSubimageMatch = rb_const_get(mCompixModule, rb_intern("SubimageMatch"));
128
+
129
+ VALUE match_obj = rb_funcall(cSubimageMatch, rb_intern("new"), 4, INT2NUM(coord_x), INT2NUM(coord_y),
130
+ INT2NUM(pixels_compared), INT2NUM(pixels_matched));
131
+ return match_obj;
132
+ }
@@ -0,0 +1,31 @@
1
+ #ifndef COMPIX_H
2
+ #define COMPIX_H
3
+
4
+ #include <ruby.h>
5
+ #include <stdbool.h>
6
+
7
+
8
+
9
+ // Types and macros from OilyPNG for compatibility
10
+ typedef uint32_t PIXEL; // Pixels use 32 bits unsigned integers
11
+ typedef unsigned char BYTE; // Bytes use 8 bits unsigned integers
12
+ #define R_BYTE(pixel) ((BYTE) (((pixel) & (PIXEL) 0xff000000) >> 24))
13
+ #define G_BYTE(pixel) ((BYTE) (((pixel) & (PIXEL) 0x00ff0000) >> 16))
14
+ #define B_BYTE(pixel) ((BYTE) (((pixel) & (PIXEL) 0x0000ff00) >> 8))
15
+ #define A_BYTE(pixel) ((BYTE) (((pixel) & (PIXEL) 0x000000ff)))
16
+
17
+ void Init_compix();
18
+
19
+ VALUE find_subimage(VALUE self, VALUE subimage, VALUE bigimage, VALUE threshold);
20
+
21
+ VALUE initialize_subimage_match_obj(int coord_x, int coord_y, int pixels_compared, int pixels_matched);
22
+
23
+ int compare_at(PIXEL *pixelsSmall, PIXEL *pixelsBig, int thres, int bigXoffset, int bigYoffset,
24
+ int siwidth, int siheight, int sswidth, int ssheight);
25
+
26
+ bool compare_pixels(PIXEL pone, PIXEL ptwo, int threshold);
27
+
28
+ // The bytearray_ptr should be allocated for the correct size.
29
+ PIXEL* image_to_bytearray(PIXEL *bytearray_ptr, VALUE image);
30
+
31
+ #endif
@@ -1,7 +1,6 @@
1
- require 'compix.so'
2
-
3
- #class Compix
4
- # module CompareImagePixels
5
- #
6
- # end
7
- #end
1
+ require 'compix.so'
2
+ require 'compix/match.rb'
3
+
4
+ module Compix
5
+
6
+ end
@@ -0,0 +1,27 @@
1
+ require 'chunky_png'
2
+
3
+
4
+ class Compix::SubimageMatch
5
+ attr_reader :coordinate_x, :coordinate_y, :pixels_compared, :pixels_matched
6
+
7
+ def initialize(coord_x, coord_y, pixels_compared, pixels_matched)
8
+ raise ArgumentError.new("Matched more pixels ('#{pixels_matched}') than compared ('#{pixels_compared}')") if pixels_compared < pixels_matched
9
+ @coordinate_x = coord_x
10
+ @coordinate_y = coord_y
11
+ @pixels_compared = pixels_compared
12
+ @pixels_matched = pixels_matched
13
+ end
14
+
15
+ def match_percentage
16
+ return 0 if pixels_compared == 0
17
+ pixels_matched.to_f / pixels_compared
18
+ end
19
+
20
+ def eql?(other)
21
+ other.class.eql?(self.class) && other.state.eql?(self.state)
22
+ end
23
+
24
+ def state
25
+ [@coordinate_x, @coordinate_y, @pixels_compared, @pixels_matched]
26
+ end
27
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Appelberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-10-24 00:00:00.000000000 Z
11
+ date: 2014-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -24,6 +24,48 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: oily_png
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
27
69
  description:
28
70
  email:
29
71
  executables: []
@@ -32,9 +74,11 @@ extensions:
32
74
  extra_rdoc_files: []
33
75
  files:
34
76
  - ext/compix/compix.c
77
+ - ext/compix/compix.h
35
78
  - ext/compix/extconf.rb
36
79
  - lib/compix.rb
37
- homepage:
80
+ - lib/compix/match.rb
81
+ homepage: https://github.com/jappelbe/compix_tmp
38
82
  licenses: []
39
83
  metadata: {}
40
84
  post_install_message: