compix 0.0.5 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: