Trong vài tuần qua, tôi đã làm việc với hình ảnh trong vật thể-c và nhận thấy rất nhiều hành vi kỳ lạ. Đầu tiên, giống như nhiều người khác, tôi đã gặp vấn đề này khi hình ảnh được chụp bằng máy ảnh (hoặc được chụp bằng máy ảnh của người khác và MMS'd cho tôi) bị xoay 90 độ. Tôi không chắc tại sao trên thế giới điều này lại xảy ra (do đó là câu hỏi của tôi ) nhưng tôi đã có thể nghĩ ra một công việc rẻ tiền.
Câu hỏi của tôi lần này là tại sao điều này lại xảy ra ? Tại sao Apple xoay hình ảnh? Khi tôi chụp ảnh với máy ảnh hướng lên bên phải, trừ khi tôi thực hiện mã đã đề cập ở trên, khi tôi lưu ảnh, nó sẽ được lưu xoay. Bây giờ, cách giải quyết của tôi đã ổn cho đến vài ngày trước.
Ứng dụng của tôi sửa đổi các pixel riêng lẻ của một hình ảnh, cụ thể là kênh alpha của PNG (vì vậy bất kỳ chuyển đổi JPEG nào đều bị loại khỏi cửa sổ đối với kịch bản của tôi). Một vài ngày trước, tôi nhận thấy rằng mặc dù hình ảnh được hiển thị chính xác trong ứng dụng của tôi nhờ mã giải pháp thay thế, nhưng khi thuật toán của tôi sửa đổi các pixel riêng lẻ của hình ảnh, nó cho rằng hình ảnh đã được xoay. Vì vậy, thay vì sửa đổi các pixel ở trên cùng của hình ảnh, nó sẽ sửa đổi các pixel ở bên cạnh của hình ảnh (vì nó nghĩ rằng nó nên được xoay)! Tôi không thể tìm ra cách xoay hình ảnh trong bộ nhớ - lý tưởng là tôi muốn xóa imageOrientation
tất cả lá cờ đó cùng nhau.
Đây là một cái gì đó khác cũng làm tôi bối rối ... Khi tôi chụp ảnh, mã imageOrientation
được đặt thành 3. Mã giải pháp của tôi đủ thông minh để nhận ra điều này và lật nó để người dùng không bao giờ nhận thấy. Ngoài ra, mã của tôi để lưu hình ảnh vào thư viện nhận ra điều này, lật nó, sau đó lưu nó để nó xuất hiện trong thư viện chính xác.
Mã đó trông giống như vậy:
NSData* pngdata = UIImagePNGRepresentation (self.workingImage); //PNG wrap
UIImage* img = [self rotateImageAppropriately:[UIImage imageWithData:pngdata]];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
Khi tôi tải hình ảnh mới lưu này vào ứng dụng của mình, giá trị imageOrientation
là 0 - chính xác những gì tôi muốn xem và giải pháp xoay vòng của tôi thậm chí không cần chạy (lưu ý: khi tải hình ảnh từ internet thay vì hình ảnh được chụp bằng máy ảnh , imageOrientation
luôn luôn là 0, dẫn đến hành vi hoàn hảo). Vì một số lý do, mã lưu của tôi dường như xóa sạch imageOrientation
cờ này . Tôi đã hy vọng chỉ ăn cắp mã đó và sử dụng nó để xóa imageOrientation của mình ngay sau khi người dùng chụp ảnh và thêm nó vào ứng dụng, nhưng nó dường như không hoạt động. Làm UIImageWriteToSavedPhotosAlbum
điều gì đó đặc biệt với imageOrientation
?
Cách khắc phục tốt nhất cho vấn đề này là chỉ thổi bay imageOrientation
ngay sau khi người dùng chụp ảnh xong. Tôi cho rằng Apple thực hiện hành vi xoay vòng là có lý do, phải không? Một vài người cho rằng đây là một khiếm khuyết của Apple.
(... nếu bạn vẫn chưa bị lạc ... Lưu ý 2: Khi tôi chụp ảnh ngang, mọi thứ dường như hoạt động hoàn hảo, giống như ảnh chụp từ internet)
BIÊN TẬP:
Dưới đây là một số hình ảnh và kịch bản thực sự trông như thế nào. Dựa trên các bình luận cho đến nay, có vẻ như hành vi kỳ lạ này không chỉ là một hành vi của iPhone, mà tôi nghĩ là tốt.
Đây là hình ảnh của bức ảnh tôi đã chụp bằng điện thoại của mình (lưu ý hướng phù hợp), nó xuất hiện chính xác như trên điện thoại của tôi khi tôi chụp ảnh:
Đây là hình ảnh trông như thế nào trong Gmail sau khi tôi gửi nó qua email cho chính mình (có vẻ như Gmail xử lý nó đúng cách):
Đây là hình ảnh trông giống như một hình thu nhỏ trong cửa sổ (có vẻ như nó không được xử lý đúng cách):
Và đây là hình ảnh thực tế trông như thế nào khi được mở bằng Windows Photo Viewer (vẫn chưa được xử lý đúng cách):
Sau tất cả các bình luận về câu hỏi này, đây là những gì tôi đang nghĩ ... iPhone chụp ảnh và nói "để hiển thị đúng cách, nó cần phải được xoay 90 độ". Thông tin này sẽ nằm trong dữ liệu EXIF. (Tại sao nó cần được xoay 90 độ, chứ không phải mặc định là thẳng đứng, tôi không biết). Từ đây, Gmail đủ thông minh để đọc và phân tích dữ liệu EXIF đó và hiển thị đúng cách. Tuy nhiên, Windows không đủ thông minh để đọc dữ liệu EXIF và do đó hiển thị hình ảnh không đúng cách . Những giả định của tôi có đúng không?