Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MR414N-ID
GitHub Repository: MR414N-ID/botku2
Path: blob/master/node_modules/@jimp/plugin-crop/es/index.js
1126 views
1
"use strict";
2
3
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5
Object.defineProperty(exports, "__esModule", {
6
value: true
7
});
8
exports["default"] = pluginCrop;
9
10
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
12
var _utils = require("@jimp/utils");
13
14
/* eslint-disable no-labels */
15
function pluginCrop(event) {
16
/**
17
* Crops the image at a given point to a give size
18
* @param {number} x the x coordinate to crop form
19
* @param {number} y the y coordinate to crop form
20
* @param w the width of the crop region
21
* @param h the height of the crop region
22
* @param {function(Error, Jimp)} cb (optional) a callback for when complete
23
* @returns {Jimp} this for chaining of methods
24
*/
25
event('crop', function (x, y, w, h, cb) {
26
if (typeof x !== 'number' || typeof y !== 'number') return _utils.throwError.call(this, 'x and y must be numbers', cb);
27
if (typeof w !== 'number' || typeof h !== 'number') return _utils.throwError.call(this, 'w and h must be numbers', cb); // round input
28
29
x = Math.round(x);
30
y = Math.round(y);
31
w = Math.round(w);
32
h = Math.round(h);
33
34
if (x === 0 && w === this.bitmap.width) {
35
// shortcut
36
var start = w * y + x << 2;
37
var end = start + h * w << 2;
38
this.bitmap.data = this.bitmap.data.slice(start, end);
39
} else {
40
var bitmap = Buffer.allocUnsafe(w * h * 4);
41
var offset = 0;
42
this.scanQuiet(x, y, w, h, function (x, y, idx) {
43
var data = this.bitmap.data.readUInt32BE(idx, true);
44
bitmap.writeUInt32BE(data, offset, true);
45
offset += 4;
46
});
47
this.bitmap.data = bitmap;
48
}
49
50
this.bitmap.width = w;
51
this.bitmap.height = h;
52
53
if ((0, _utils.isNodePattern)(cb)) {
54
cb.call(this, null, this);
55
}
56
57
return this;
58
});
59
return {
60
"class": {
61
/**
62
* Autocrop same color borders from this image
63
* @param {number} tolerance (optional): a percent value of tolerance for pixels color difference (default: 0.0002%)
64
* @param {boolean} cropOnlyFrames (optional): flag to crop only real frames: all 4 sides of the image must have some border (default: true)
65
* @param {function(Error, Jimp)} cb (optional): a callback for when complete (default: no callback)
66
* @returns {Jimp} this for chaining of methods
67
*/
68
autocrop: function autocrop() {
69
var w = this.bitmap.width;
70
var h = this.bitmap.height;
71
var minPixelsPerSide = 1; // to avoid cropping completely the image, resulting in an invalid 0 sized image
72
73
var cb; // callback
74
75
var leaveBorder = 0; // Amount of pixels in border to leave
76
77
var tolerance = 0.0002; // percent of color difference tolerance (default value)
78
79
var cropOnlyFrames = true; // flag to force cropping only if the image has a real "frame"
80
// i.e. all 4 sides have some border (default value)
81
82
var cropSymmetric = false; // flag to force cropping top be symmetric.
83
// i.e. north and south / east and west are cropped by the same value
84
85
var ignoreSides = {
86
north: false,
87
south: false,
88
east: false,
89
west: false
90
}; // parse arguments
91
92
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
93
args[_key] = arguments[_key];
94
}
95
96
for (var a = 0, len = args.length; a < len; a++) {
97
if (typeof args[a] === 'number') {
98
// tolerance value passed
99
tolerance = args[a];
100
}
101
102
if (typeof args[a] === 'boolean') {
103
// cropOnlyFrames value passed
104
cropOnlyFrames = args[a];
105
}
106
107
if (typeof args[a] === 'function') {
108
// callback value passed
109
cb = args[a];
110
}
111
112
if ((0, _typeof2["default"])(args[a]) === 'object') {
113
// config object passed
114
var config = args[a];
115
116
if (typeof config.tolerance !== 'undefined') {
117
tolerance = config.tolerance;
118
}
119
120
if (typeof config.cropOnlyFrames !== 'undefined') {
121
cropOnlyFrames = config.cropOnlyFrames;
122
}
123
124
if (typeof config.cropSymmetric !== 'undefined') {
125
cropSymmetric = config.cropSymmetric;
126
}
127
128
if (typeof config.leaveBorder !== 'undefined') {
129
leaveBorder = config.leaveBorder;
130
}
131
132
if (typeof config.ignoreSides !== 'undefined') {
133
ignoreSides = config.ignoreSides;
134
}
135
}
136
}
137
/**
138
* All borders must be of the same color as the top left pixel, to be cropped.
139
* It should be possible to crop borders each with a different color,
140
* but since there are many ways for corners to intersect, it would
141
* introduce unnecessary complexity to the algorithm.
142
*/
143
// scan each side for same color borders
144
145
146
var colorTarget = this.getPixelColor(0, 0); // top left pixel color is the target color
147
148
var rgba1 = this.constructor.intToRGBA(colorTarget); // for north and east sides
149
150
var northPixelsToCrop = 0;
151
var eastPixelsToCrop = 0;
152
var southPixelsToCrop = 0;
153
var westPixelsToCrop = 0; // north side (scan rows from north to south)
154
155
colorTarget = this.getPixelColor(0, 0);
156
157
if (!ignoreSides.north) {
158
north: for (var y = 0; y < h - minPixelsPerSide; y++) {
159
for (var x = 0; x < w; x++) {
160
var colorXY = this.getPixelColor(x, y);
161
var rgba2 = this.constructor.intToRGBA(colorXY);
162
163
if (this.constructor.colorDiff(rgba1, rgba2) > tolerance) {
164
// this pixel is too distant from the first one: abort this side scan
165
break north;
166
}
167
} // this row contains all pixels with the same color: increment this side pixels to crop
168
169
170
northPixelsToCrop++;
171
}
172
} // east side (scan columns from east to west)
173
174
175
colorTarget = this.getPixelColor(w, 0);
176
177
if (!ignoreSides.east) {
178
east: for (var _x = 0; _x < w - minPixelsPerSide; _x++) {
179
for (var _y = 0 + northPixelsToCrop; _y < h; _y++) {
180
var _colorXY = this.getPixelColor(_x, _y);
181
182
var _rgba = this.constructor.intToRGBA(_colorXY);
183
184
if (this.constructor.colorDiff(rgba1, _rgba) > tolerance) {
185
// this pixel is too distant from the first one: abort this side scan
186
break east;
187
}
188
} // this column contains all pixels with the same color: increment this side pixels to crop
189
190
191
eastPixelsToCrop++;
192
}
193
} // south side (scan rows from south to north)
194
195
196
colorTarget = this.getPixelColor(0, h);
197
198
if (!ignoreSides.south) {
199
south: for (var _y2 = h - 1; _y2 >= northPixelsToCrop + minPixelsPerSide; _y2--) {
200
for (var _x2 = w - eastPixelsToCrop - 1; _x2 >= 0; _x2--) {
201
var _colorXY2 = this.getPixelColor(_x2, _y2);
202
203
var _rgba2 = this.constructor.intToRGBA(_colorXY2);
204
205
if (this.constructor.colorDiff(rgba1, _rgba2) > tolerance) {
206
// this pixel is too distant from the first one: abort this side scan
207
break south;
208
}
209
} // this row contains all pixels with the same color: increment this side pixels to crop
210
211
212
southPixelsToCrop++;
213
}
214
} // west side (scan columns from west to east)
215
216
217
colorTarget = this.getPixelColor(w, h);
218
219
if (!ignoreSides.west) {
220
west: for (var _x3 = w - 1; _x3 >= 0 + eastPixelsToCrop + minPixelsPerSide; _x3--) {
221
for (var _y3 = h - 1; _y3 >= 0 + northPixelsToCrop; _y3--) {
222
var _colorXY3 = this.getPixelColor(_x3, _y3);
223
224
var _rgba3 = this.constructor.intToRGBA(_colorXY3);
225
226
if (this.constructor.colorDiff(rgba1, _rgba3) > tolerance) {
227
// this pixel is too distant from the first one: abort this side scan
228
break west;
229
}
230
} // this column contains all pixels with the same color: increment this side pixels to crop
231
232
233
westPixelsToCrop++;
234
}
235
} // decide if a crop is needed
236
237
238
var doCrop = false; // apply leaveBorder
239
240
westPixelsToCrop -= leaveBorder;
241
eastPixelsToCrop -= leaveBorder;
242
northPixelsToCrop -= leaveBorder;
243
southPixelsToCrop -= leaveBorder;
244
245
if (cropSymmetric) {
246
var horizontal = Math.min(eastPixelsToCrop, westPixelsToCrop);
247
var vertical = Math.min(northPixelsToCrop, southPixelsToCrop);
248
westPixelsToCrop = horizontal;
249
eastPixelsToCrop = horizontal;
250
northPixelsToCrop = vertical;
251
southPixelsToCrop = vertical;
252
} // make sure that crops are >= 0
253
254
255
westPixelsToCrop = westPixelsToCrop >= 0 ? westPixelsToCrop : 0;
256
eastPixelsToCrop = eastPixelsToCrop >= 0 ? eastPixelsToCrop : 0;
257
northPixelsToCrop = northPixelsToCrop >= 0 ? northPixelsToCrop : 0;
258
southPixelsToCrop = southPixelsToCrop >= 0 ? southPixelsToCrop : 0; // safety checks
259
260
var widthOfRemainingPixels = w - (westPixelsToCrop + eastPixelsToCrop);
261
var heightOfRemainingPixels = h - (southPixelsToCrop + northPixelsToCrop);
262
263
if (cropOnlyFrames) {
264
// crop image if all sides should be cropped
265
doCrop = eastPixelsToCrop !== 0 && northPixelsToCrop !== 0 && westPixelsToCrop !== 0 && southPixelsToCrop !== 0;
266
} else {
267
// crop image if at least one side should be cropped
268
doCrop = eastPixelsToCrop !== 0 || northPixelsToCrop !== 0 || westPixelsToCrop !== 0 || southPixelsToCrop !== 0;
269
}
270
271
if (doCrop) {
272
// do the real crop
273
this.crop(eastPixelsToCrop, northPixelsToCrop, widthOfRemainingPixels, heightOfRemainingPixels);
274
}
275
276
if ((0, _utils.isNodePattern)(cb)) {
277
cb.call(this, null, this);
278
}
279
280
return this;
281
}
282
}
283
};
284
}
285
//# sourceMappingURL=index.js.map
286