@@ -260,10 +260,11 @@ public static function fromTensor(Tensor $tensor, string $channelFormat = 'CHW')
260260
261261 $ image = self ::$ imagine ->create (new Box ($ width , $ height ));
262262
263- if ( $ image instanceof \ Imagine \ Vips \Image) {
264- $ data = pack ( ' C* ' , ... $ tensor ->buffer ()-> toArray () );
263+ // Make sure the tensor is the right data type
264+ $ tensor = $ tensor ->to (Tensor::uint8 );
265265
266- $ vipImage = $ image ->getVips ()::newFromMemory ($ data , $ width , $ height , $ channels , 'uchar ' );
266+ if ($ image instanceof \Imagine \Vips \Image) {
267+ $ vipImage = $ image ->getVips ()::newFromMemory ($ tensor ->buffer ()->dump (), $ width , $ height , $ channels , 'uchar ' );
267268
268269 $ image ->setVips ($ vipImage , true );
269270
@@ -279,10 +280,7 @@ public static function fromTensor(Tensor $tensor, string $channelFormat = 'CHW')
279280 default => throw new Exception ("Unsupported number of channels: $ channels " ),
280281 };
281282
282- $ bufferArray = [];
283- for ($ i = 0 ; $ i < $ tensor ->size (); $ i ++) {
284- $ bufferArray [] = $ tensor ->buffer ()[$ i ];
285- }
283+ $ bufferArray = $ tensor ->toBufferArray ();
286284
287285 $ image ->getImagick ()->importImagePixels (0 , 0 , $ width , $ height , $ map , Imagick::PIXEL_CHAR , $ bufferArray );
288286
@@ -311,9 +309,10 @@ public function toTensor(string $channelFormat = 'CHW'): Tensor
311309 $ width = $ this ->image ->getSize ()->getWidth ();
312310 $ height = $ this ->image ->getSize ()->getHeight ();
313311
314- $ pixels = $ this ->pixelData ();
312+ $ pixelData = $ this ->getPixelData ();
315313
316- $ tensor = new Tensor ($ pixels , Tensor::float32, [$ height , $ width , $ this ->channels ]);
314+ $ tensor = Tensor::fromString ($ pixelData , Tensor::uint8, [$ height , $ width , $ this ->channels ])
315+ ->to (Tensor::float32);
317316
318317 if ($ channelFormat === 'HWC ' ) {
319318 // Do nothing
@@ -326,20 +325,17 @@ public function toTensor(string $channelFormat = 'CHW'): Tensor
326325 return $ tensor ;
327326 }
328327
329- /**
330- * @return array
331- */
332- public function pixelData (): array
328+ public function getPixelData (): string
333329 {
334- $ width = $ this ->image -> getSize ()-> getWidth ();
335- $ height = $ this ->image -> getSize ()-> getHeight ();
330+ $ width = $ this ->width ();
331+ $ height = $ this ->height ();
336332
337- // If it's a Vips image , we can extract the pixel data directly
333+ /** For Vips images , we can export the pixel data directly */
338334 if ($ this ->image instanceof \Imagine \Vips \Image) {
339- return $ this ->image ->getVips ()->writeToArray ();
335+ return $ this ->image ->getVips ()->writeToMemory ();
340336 }
341337
342- // If it's an Imagick image , we can export the pixel data directly
338+ /** For Imagick images , we can export the pixel data directly */
343339 if ($ this ->image instanceof \Imagine \Imagick \Image) {
344340 $ map = match ($ this ->channels ) {
345341 1 => 'I ' ,
@@ -349,12 +345,17 @@ public function pixelData(): array
349345 default => throw new Exception ("Unsupported number of channels: $ this ->channels " ),
350346 };
351347
352- return $ this ->image ->getImagick ()->exportImagePixels (0 , 0 , $ width , $ height , $ map , Imagick::PIXEL_CHAR );
348+ $ pixels = $ this ->image ->getImagick ()->exportImagePixels (0 , 0 , $ width , $ height , $ map , Imagick::PIXEL_CHAR );
349+
350+ return pack ('C* ' , ...$ pixels );
353351 }
354352
355- // I didn't find an in-built method to extract pixel data from a GD image, so I'm using this ugly
356- // brute-force method, suggested by @DewiMorgan on StackOverflow: https://stackoverflow.com/a/30136602/11209184.
357- // It's faster than other methods I tried, and rivals the speed of the Imagick method so I'll keep it for now.
353+ /** For GD images, we need to extract the pixel data manually
354+ *
355+ * I didn't find an in-built method to extract pixel data from a GD image, so I'm using this ugly
356+ * brute-force method, suggested by @DewiMorgan on StackOverflow: https://stackoverflow.com/a/30136602/11209184.
357+ * It's tons faster than other methods I tried, and rivals the speed of the Imagick method, so I'll keep it for now.
358+ */
358359 $ alphaLookup = [
359360 0x00000000 => "\xff" , 0x01000000 => "\xfd" , 0x02000000 => "\xfb" , 0x03000000 => "\xf9" ,
360361 0x04000000 => "\xf7" , 0x05000000 => "\xf5" , 0x06000000 => "\xf3" , 0x07000000 => "\xf1" ,
@@ -440,9 +441,7 @@ public function pixelData(): array
440441 }
441442 }
442443
443- $ data = unpack ('C* ' , $ imageData );
444-
445- return array_values ($ data );
444+ return $ imageData ;
446445 }
447446
448447 public function save (string $ path ): void
0 commit comments