344
344
* to append a constant 255 band to an image, perhaps to add an alpha channel. Of
345
345
* course you can also write:
346
346
*
347
- * ```ruby
347
+ * ```php
348
348
* $result = $image->bandjoin($image2);
349
349
* $result = $image->bandjoin([image2, image3]);
350
350
* $result = Image::bandjoin([image1, image2, image3]);
353
353
*
354
354
* and so on.
355
355
*
356
+ * # Array access
357
+ *
358
+ * Images can be treated as arrays of bands. You can write:
359
+ *
360
+ * ```php
361
+ * $result = $image[1];
362
+ * ```
363
+ *
364
+ * to get band 1 from an image (green, in an RGB image).
365
+ *
366
+ * You can assign to bands as well. You can write:
367
+ *
368
+ * ```php
369
+ * $image[1] = $other_image;
370
+ * ```
371
+ *
372
+ * And band 1 will be replaced by all the bands in `$other_image` using
373
+ * `bandjoin`. Use no offset to mean append, use -1 to mean prepend:
374
+ *
375
+ * ```php
376
+ * $image[] = $other_image; // append bands from other
377
+ * $image[-1] = $other_image; // prepend bands from other
378
+ * ```
379
+ *
380
+ * You can use number and array constants as well, for example:
381
+ *
382
+ * ```php
383
+ * $image[] = 255; // append a constant 255
384
+ * $image[1] = [1, 2, 3]; // swap band 1 for three constant bands
385
+ * ```
386
+ *
387
+ * Finally, you can delete bands with `unset`:
388
+ *
389
+ * ```php
390
+ * unset($image[1]); // remove band 1
391
+ * ```
392
+ *
356
393
* # Exceptions
357
394
*
358
395
* The wrapper spots errors from vips operations and throws
@@ -1162,7 +1199,7 @@ public function hasAlpha(): bool
1162
1199
}
1163
1200
1164
1201
/**
1165
- * Our ArrayAccess interface ... we allow [] to get band .
1202
+ * Does band exist in image .
1166
1203
*
1167
1204
* @param mixed $offset The index to fetch.
1168
1205
*
@@ -1174,7 +1211,7 @@ public function offsetExists($offset): bool
1174
1211
}
1175
1212
1176
1213
/**
1177
- * Our ArrayAccess interface ... we allow [] to get band .
1214
+ * Get band from image .
1178
1215
*
1179
1216
* @param mixed $offset The index to fetch.
1180
1217
*
@@ -1186,28 +1223,88 @@ public function offsetGet($offset): Image
1186
1223
}
1187
1224
1188
1225
/**
1189
- * Our ArrayAccess interface ... we allow [] to get band.
1226
+ * Set a band.
1227
+ *
1228
+ * Use `$image[1] = $other_image;' to remove band 1 from this image,
1229
+ * replacing it with all the bands in `$other_image`.
1230
+ *
1231
+ * Use `$image[] = $other_image;' to append all the bands in `$other_image`
1232
+ * to `$image`.
1190
1233
*
1191
- * @param mixed $offset The index to set.
1234
+ * Use `$image[-1] = $other_image;` to prepend all the bands in
1235
+ * `$other_image` to `$image`.
1236
+ *
1237
+ * You can use constants or arrays in place of `$other_image`. Use `$image[]
1238
+ * = 255;` to append a constant 255 band, for example, or `$image[1]
1239
+ * = [1, 2];` to replace band 1 with two constant bands.
1240
+ *
1241
+ * @param int $offset The index to set.
1192
1242
* @param Image $value The band to insert
1193
1243
*
1194
- * @return Image the expanded image.
1244
+ * @return void
1195
1245
*/
1196
- public function offsetSet ($ offset , $ value ): Image
1246
+ public function offsetSet ($ offset , $ value ): void
1197
1247
{
1198
- throw new \BadMethodCallException ('Image::offsetSet: not implemented ' );
1248
+ // no offset means append
1249
+ if (is_null ($ offset )) {
1250
+ $ offset = $ this ->bands ;
1251
+ }
1252
+
1253
+ if (!is_int ($ offset )) {
1254
+ throw new \BadMethodCallException ('Image::offsetSet: offset is not integer or null ' );
1255
+ }
1256
+
1257
+ // expand constant, if necessary
1258
+ if (!($ value instanceof Image)) {
1259
+ $ value = self ::imageize ($ this , $ value );
1260
+ }
1261
+
1262
+ // number of bands to the left and right of $value
1263
+ $ n_left = min ($ this ->bands , max (0 , $ offset ));
1264
+ $ n_right = min ($ this ->bands , max (0 , $ this ->bands - 1 - $ offset ));
1265
+ $ offset = $ this ->bands - $ n_right ;
1266
+
1267
+ $ components = [];
1268
+ if ($ n_left > 0 ) {
1269
+ $ components [] = $ this ->extract_band (0 , ["n " => $ n_left ]);
1270
+ }
1271
+ $ components [] = $ value ;
1272
+ if ($ n_right ) {
1273
+ $ components [] = $ this ->extract_band ($ offset , ["n " => $ n_right ]);
1274
+ }
1275
+
1276
+ $ head = array_shift ($ components );
1277
+ $ this ->image = $ head ->bandjoin ($ components )->image ;
1199
1278
}
1200
1279
1201
1280
/**
1202
- * Our ArrayAccess interface ... we allow [] to get band .
1281
+ * Remove a band from an image .
1203
1282
*
1204
- * @param mixed $offset The index to remove.
1283
+ * @param int $offset The index to remove.
1205
1284
*
1206
- * @return Image the reduced image.
1285
+ * @return void
1207
1286
*/
1208
- public function offsetUnset ($ offset ): Image
1287
+ public function offsetUnset ($ offset ): void
1209
1288
{
1210
- throw new \BadMethodCallException ('Image::offsetUnset: not implemented ' );
1289
+ if (is_int ($ offset ) and $ offset >= 0 and $ offset < $ this ->bands ) {
1290
+ $ components = [];
1291
+ if ($ offset > 0 ) {
1292
+ $ components [] = $ this ->extract_band (0 , ["n " => $ offset ]);
1293
+ }
1294
+ if ($ offset < $ this ->bands - 1 ) {
1295
+ $ components [] = $ this ->extract_band (
1296
+ $ offset + 1 ,
1297
+ ["n " => $ this ->bands - 1 - $ offset ]
1298
+ );
1299
+ }
1300
+
1301
+ $ head = array_shift ($ components );
1302
+ if ($ components != null ) {
1303
+ $ this ->image = $ head ->bandjoin ($ components )->image ;
1304
+ } else {
1305
+ $ this ->image = $ head ->image ;
1306
+ }
1307
+ }
1211
1308
}
1212
1309
1213
1310
/**
0 commit comments