php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
gd_crop.c
Go to the documentation of this file.
1
21
22#include <stdlib.h>
23#include <string.h>
24#include <math.h>
25
26#include "gd.h"
27
28static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color);
29static int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold);
30
45{
46 gdImagePtr dst;
47 int alphaBlendingFlag;
48
49 if (gdImageTrueColor(src)) {
50 dst = gdImageCreateTrueColor(crop->width, crop->height);
51 } else {
52 dst = gdImageCreate(crop->width, crop->height);
53 }
54 if (!dst) return NULL;
55 alphaBlendingFlag = dst->alphaBlendingFlag;
57 gdImageCopy(dst, src, 0, 0, crop->x, crop->y, crop->width, crop->height);
58 gdImageAlphaBlending(dst, alphaBlendingFlag);
59
60 return dst;
61}
62
80{
81 const int width = gdImageSX(im);
82 const int height = gdImageSY(im);
83
84 int x,y;
85 int color, match;
86 gdRect crop;
87
88 crop.x = 0;
89 crop.y = 0;
90 crop.width = 0;
91 crop.height = 0;
92
93 switch (mode) {
96 break;
97
98 case GD_CROP_BLACK:
99 color = gdImageColorClosestAlpha(im, 0, 0, 0, 0);
100 break;
101
102 case GD_CROP_WHITE:
103 color = gdImageColorClosestAlpha(im, 255, 255, 255, 0);
104 break;
105
106 case GD_CROP_SIDES:
107 gdGuessBackgroundColorFromCorners(im, &color);
108 break;
109
110 case GD_CROP_DEFAULT:
111 default:
113 break;
114 }
115
116 /* TODO: Add gdImageGetRowPtr and works with ptr at the row level
117 * for the true color and palette images
118 * new formats will simply work with ptr
119 */
120 match = 1;
121 for (y = 0; match && y < height; y++) {
122 for (x = 0; match && x < width; x++) {
123 int c2 = gdImageGetPixel(im, x, y);
124 match = (color == c2);
125 }
126 }
127
128 /* Whole image would be cropped > bye */
129 if (match) {
130 return NULL;
131 }
132
133 crop.y = y - 1;
134
135 match = 1;
136 for (y = height - 1; match && y >= 0; y--) {
137 for (x = 0; match && x < width; x++) {
138 match = (color == gdImageGetPixel(im, x,y));
139 }
140 }
141 crop.height = y - crop.y + 2;
142
143 match = 1;
144 for (x = 0; match && x < width; x++) {
145 for (y = 0; match && y < crop.y + crop.height; y++) {
146 match = (color == gdImageGetPixel(im, x,y));
147 }
148 }
149 crop.x = x - 1;
150
151 match = 1;
152 for (x = width - 1; match && x >= 0; x--) {
153 for (y = 0; match && y < crop.y + crop.height; y++) {
154 match = (color == gdImageGetPixel(im, x,y));
155 }
156 }
157 crop.width = x - crop.x + 2;
158
159 return gdImageCrop(im, &crop);
160}
161/*TODOs: Implement DeltaE instead, way better perceptual differences */
181gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold)
182{
183 const int width = gdImageSX(im);
184 const int height = gdImageSY(im);
185
186 int x,y;
187 int match;
188 gdRect crop;
189
190 crop.x = 0;
191 crop.y = 0;
192 crop.width = 0;
193 crop.height = 0;
194
195 /* Pierre: crop everything sounds bad */
196 if (threshold > 100.0) {
197 return NULL;
198 }
199
200 if (!gdImageTrueColor(im) && color >= gdImageColorsTotal(im)) {
201 return NULL;
202 }
203
204 /* TODO: Add gdImageGetRowPtr and works with ptr at the row level
205 * for the true color and palette images
206 * new formats will simply work with ptr
207 */
208 match = 1;
209 for (y = 0; match && y < height; y++) {
210 for (x = 0; match && x < width; x++) {
211 match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
212 }
213 }
214
215 /* Whole image would be cropped > bye */
216 if (match) {
217 return NULL;
218 }
219
220 crop.y = y - 1;
221
222 match = 1;
223 for (y = height - 1; match && y >= 0; y--) {
224 for (x = 0; match && x < width; x++) {
225 match = (gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) > 0;
226 }
227 }
228 crop.height = y - crop.y + 2;
229
230 match = 1;
231 for (x = 0; match && x < width; x++) {
232 for (y = 0; match && y < crop.y + crop.height; y++) {
233 match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
234 }
235 }
236 crop.x = x - 1;
237
238 match = 1;
239 for (x = width - 1; match && x >= 0; x--) {
240 for (y = 0; match && y < crop.y + crop.height; y++) {
241 match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
242 }
243 }
244 crop.width = x - crop.x + 2;
245
246 return gdImageCrop(im, &crop);
247}
248
249/* This algorithm comes from pnmcrop (http://netpbm.sourceforge.net/)
250 * Three steps:
251 * - if 3 corners are equal.
252 * - if two are equal.
253 * - Last solution: average the colors
254 */
255static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color)
256{
257 const int tl = gdImageGetPixel(im, 0, 0);
258 const int tr = gdImageGetPixel(im, gdImageSX(im) - 1, 0);
259 const int bl = gdImageGetPixel(im, 0, gdImageSY(im) -1);
260 const int br = gdImageGetPixel(im, gdImageSX(im) - 1, gdImageSY(im) -1);
261
262 if (tr == bl && tr == br) {
263 *color = tr;
264 return 3;
265 } else if (tl == bl && tl == br) {
266 *color = tl;
267 return 3;
268 } else if (tl == tr && tl == br) {
269 *color = tl;
270 return 3;
271 } else if (tl == tr && tl == bl) {
272 *color = tl;
273 return 3;
274 } else if (tl == tr || tl == bl || tl == br) {
275 *color = tl;
276 return 2;
277 } else if (tr == bl || tr == br) {
278 *color = tr;
279 return 2;
280 } else if (br == bl) {
281 *color = bl;
282 return 2;
283 } else {
284 register int r,b,g,a;
285
286 r = (int)(0.5f + (gdImageRed(im, tl) + gdImageRed(im, tr) + gdImageRed(im, bl) + gdImageRed(im, br)) / 4);
287 g = (int)(0.5f + (gdImageGreen(im, tl) + gdImageGreen(im, tr) + gdImageGreen(im, bl) + gdImageGreen(im, br)) / 4);
288 b = (int)(0.5f + (gdImageBlue(im, tl) + gdImageBlue(im, tr) + gdImageBlue(im, bl) + gdImageBlue(im, br)) / 4);
289 a = (int)(0.5f + (gdImageAlpha(im, tl) + gdImageAlpha(im, tr) + gdImageAlpha(im, bl) + gdImageAlpha(im, br)) / 4);
290 *color = gdImageColorClosestAlpha(im, r, g, b, a);
291 return 0;
292 }
293}
294
295static int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold)
296{
297 const int dr = gdImageRed(im, col1) - gdImageRed(im, col2);
298 const int dg = gdImageGreen(im, col1) - gdImageGreen(im, col2);
299 const int db = gdImageBlue(im, col1) - gdImageBlue(im, col2);
300 const int da = gdImageAlpha(im, col1) - gdImageAlpha(im, col2);
301 const int dist = dr * dr + dg * dg + db * db + da * da;
302
303 return (100.0 * dist / 195075) < threshold;
304}
305
306/*
307 * To be implemented when we have more image formats.
308 * Buffer like gray8 gray16 or rgb8 will require some tweak
309 * and can be done in this function (called from the autocrop
310 * function. (Pierre)
311 */
312#if 0
313static int colors_equal (const int col1, const in col2)
314{
315
316}
317#endif
char * mode
#define gdImageBlue(im, c)
Definition gd.h:775
struct gdRect * gdRectPtr
#define gdImageTrueColor(im)
Definition gd.h:766
@ GD_CROP_TRANSPARENT
Definition gd.h:871
@ GD_CROP_WHITE
Definition gd.h:873
@ GD_CROP_BLACK
Definition gd.h:872
@ GD_CROP_SIDES
Definition gd.h:874
@ GD_CROP_DEFAULT
Definition gd.h:870
#define gdImageGetTransparent(im)
Definition gd.h:779
#define gdEffectReplace
Definition gd.h:89
#define gdImageSY(im)
Definition gd.h:769
#define gdImageSX(im)
Definition gd.h:768
#define gdImageColorsTotal(im)
Definition gd.h:770
#define gdImageGreen(im, c)
Definition gd.h:773
#define gdImageAlpha(im, c)
Definition gd.h:777
#define gdImageRed(im, c)
Definition gd.h:771
gdImage * gdImagePtr
Definition gd.h:248
gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode)
Definition gd_crop.c:79
gdImagePtr gdImageCrop(gdImagePtr src, const gdRectPtr crop)
Definition gd_crop.c:44
gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold)
Definition gd_crop.c:181
#define NULL
Definition gdcache.h:45
gdImagePtr gdImageCreate(int sx, int sy)
Definition gd.c:141
void gdImageAlphaBlending(gdImagePtr im, int alphaBlendingArg)
Definition gd.c:3037
int gdImageGetPixel(gdImagePtr im, int x, int y)
Definition gd.c:953
void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)
Definition gd.c:2312
gdImagePtr gdImageCreateTrueColor(int sx, int sy)
Definition gd.c:195
int gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a)
Definition gd.c:276
short color
file_private int match(struct magic_set *, struct magic *, size_t, const struct buffer *, size_t, int, int, int, uint16_t *, uint16_t *, int *, int *, int *, int *, int *)
Definition softmagic.c:212
int alphaBlendingFlag
Definition gd.h:225
Definition gd.h:313
int x
Definition gd.h:314
int height
Definition gd.h:315
int y
Definition gd.h:314
int width
Definition gd.h:315
$obj a
Definition test.php:84