Module: ChunkyPNGSubimage

Defined in:
lib/chunky_png_subimage/search.rb,
lib/chunky_png_subimage/version.rb,
ext/chunky_png_subimage/chunky_png_subimage.c

Constant Summary collapse

VERSION =
"0.2.0"

Class Method Summary collapse

Class Method Details

._search_subimage(*args) ⇒ Object

Exportable function to ruby, to search subimages in the image

Parameters:

  • argc

    Amount of elements in argv

  • argv

    Parameters: img array of pixels, img width, img height, search offset x, search offset y, search width, search height, singleMode (bit 1 - for subimage search, bit 0 - to stop after 1st found subimage), amount of subimages, for every subimage:

    subimage array of pixels, subimage width, subimage height
    
  • self

    Object

Returns:

  • Array of found subimages’ positions



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'ext/chunky_png_subimage/chunky_png_subimage.c', line 153

VALUE search_subimages(int argc, VALUE *argv, VALUE self)
{
	/*
	params = [img.pixels, img.width, img.height, x, y, width, height, single, subimages.length]
	subimages.each do |s|
		params << s.pixels
		params << s.width
		params << s.height
	end
	 */

	VALUE result = rb_ary_new();
	const VALUE *imgPixels;
	int imgWidth;
	int imgHeight;
	int searchX;
	int searchY;
	int searchWidth;
	int searchHeight;
	int singleMode;
	int amountSubimages;
	const unsigned int *imgReady;
	int cur = 9;
	int i;

	if (argc < 12 || (argc - 9) % 3 != 0)
		rb_raise(rb_eArgError, "wrong number of arguments");

	imgPixels = RARRAY_PTR(argv[0]);
	imgWidth = NUM2INT(argv[1]);
	imgHeight = NUM2INT(argv[2]);
	searchX = NUM2INT(argv[3]);
	searchY = NUM2INT(argv[4]);
	searchWidth = NUM2INT(argv[5]);
	searchHeight = NUM2INT(argv[6]);
	singleMode = NUM2INT(argv[7]);
	amountSubimages = NUM2INT(argv[8]);

	/* some parameters checks */
	if (searchX < 0)
		searchX = 0;
	if (searchY < 0)
		searchY = 0;
	if (searchX >= imgWidth)
		searchX = imgWidth - 1;
	if (searchY >= imgHeight)
		searchY = imgHeight - 1;
	if (searchWidth <= 0)
		searchWidth = imgWidth;
	if (searchHeight <= 0)
		searchHeight = imgHeight;
	if (searchX + searchWidth >= imgWidth)
		searchWidth = imgWidth - searchX;
	if (searchY + searchHeight >= imgHeight)
		searchHeight = imgHeight - searchY;

	/* prepare image */
	imgReady = convert_image(imgPixels, imgWidth, imgHeight);

	for (i = 0; i < amountSubimages; i++)
	{
		/* cur++ inside RARRAY_PTR might not be used as it is used in the macro multiple times */
		const VALUE *subPixels = RARRAY_PTR(argv[cur]);
		int subWidth = NUM2INT(argv[cur + 1]);
		int subHeight = NUM2INT(argv[cur + 2]);
		const unsigned int *subReady = convert_image(subPixels, subWidth, subHeight);

		VALUE r = search_single_subimage(imgReady, imgWidth, imgHeight,
				searchX, searchY, searchWidth, searchHeight,
				subReady, subWidth, subHeight, singleMode);

		xfree((void *)subReady);

		rb_ary_push(result, r);

		/* stop if the proper single mode and result is found */
		if ((singleMode & 1) && RARRAY_LEN(r) > 0)
			break;

		cur += 3;
	}

	xfree((void *)imgReady);

	return result;
}

.search_subimage(img, subimages, single = :single_same_subimage, x = 0, y = 0, width = 0, height = 0) ⇒ Object

Search subimages on the image.

Attributes

  • img - Image where search for subimages will be done

  • subimages - Subimage or an array of subimages. Just fully opaque pixels are used from any subimage.

  • single - ‘single mode’, when to stop if an subimage is found, possible values: :single_everywhere - fully stop after 1st subimage is found; :single_same_subimage - search maximum 1 subimage position, for every provided subimage; :single_subimage - stop after 1st subimage is found, but find every possible position for that subimage; anything else - search for every possible subimage multiple times.

  • x - if find subimages inside some region of image - offset x (0 by default)

  • y - if find subimages inside some region of image - offset y (0 by default)

  • width - if find subimages inside some region of image - width of that region (full image by default)

  • height - if find subimages inside some region of image - height of that region (full image by default)

Output

Method returns:

  • An array of arrays with positions of found subimages.

  • If just single subimage is provided (without array) - then the output also does not contain outer array.

Examples

ChunkyPNGSubimage.search_subimage img, sub



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/chunky_png_subimage/search.rb', line 56

def self.search_subimage img, subimages, single = :single_same_subimage, x = 0, y = 0, width = 0, height = 0
  many_subimages = subimages.is_a? Array
  subimages = [subimages] unless many_subimages
  case single
  when :single_everywhere
    single = 3
  when :single_same_subimage # just 1 result is needed per subimage
    single = 2
  when :single_subimage # single image to find
    single = 1
  else
    single = 0
  end
  params = [img.pixels, img.width, img.height, x, y, width, height, single, subimages.length]
  subimages.each do |s|
    params << s.pixels
    params << s.width
    params << s.height
  end
  res = self._search_subimage *params
  res = res[0] if (!many_subimages && res.is_a?(Array))
  res
end