brendan-duncan / image

Dart Image Library for opening, manipulating, and saving various different image file formats.
MIT License
1.17k stars 265 forks source link

[Bug?] Image shifts when create Image.fromBytes() #599

Closed FourwingsY closed 9 months ago

FourwingsY commented 9 months ago

in iOS, I got image from camera, and convert to Image object to crop and resize.

import 'package:camera/camera.dart';
import 'package:image/image.dart' as imglib;

CameraImage image; // from cameraController.startImageStream((image) { ... });
final img = imglib.Image.fromBytes(
  width: image.width,
  height: image.height,
  bytes: image.planes.first.bytes.buffer,
  rowStride: image.planes.first.bytesPerRow,
  numChannels: 4,
  order: imglib.ChannelOrder.bgra,
);

But even before crop or resize, It renders strangely.

import 'package:flutter/material.dart' as ui;

// ...

return Container(
  child: ui.Image.memory(imglib.encodeJpg(img));
);

Result Image was bit shifted (6px) like this way.

IMG_0884

Do I have any misunderstanding about handling images?

p.s. I manually moved that strange left parts, and noticed It is not matched on moved horizontally. It seems pixels are got from 1px upper side.

Screenshot 2023-12-22 at 02 55 21 Screenshot 2023-12-22 at 02 55 28
FourwingsY commented 9 months ago

Did some investigation : Image created by Image.fromBytes has some strange 28 bytes in front of rgb values.

[7, 13, 0, 7, 108, 112, 6, 97, 115, 101, 110, 12, 4, 13, 1, 7, 121, 98, 5, 116, 8, 115, 101, 255, 56, 64, 0, 0]

last four bytes are changed when input image size changes. So I assume this is some type of image file headers....

FourwingsY commented 9 months ago

Okay, image.planes.first.bytes.buffer.asUint8List(0, 40) gives me a same bytes.... So this is not this library's issue.

FourwingsY commented 9 months ago

Nobody knows about this 28 bytes.

https://stackoverflow.com/a/76302695/5107380

brendan-duncan commented 9 months ago

I'm glad you figured it out. You can use the bytesOffset argument in fromBytes to skip those first 28 bytes.