macos - Image from ImagePicker in landscape - Stack Overflow
Issue: Images from an ImagePicker (macOS) are displaying in landscape regardless of their actual orientation.
Desired Result: Images that are portrait should display as portrait
Steps to duplicate: Copy and paste the below code into a fresh project. Click the Select a photo button and select a picture that is portrait orientation. When it displays it will be rotated 90 degrees as landscape
Discussion: This seems to be related to the Image view object as it happens even within a PhotosPicker
Code: (import PhotosUI at top)
struct ContentView: View {
@State private var pickerItem: PhotosPickerItem?
@State private var selectedImage: Image?
var body: some View {
VStack {
PhotosPicker("Select a photo", selection: $pickerItem)
.onChange(of: pickerItem) {
Task {
selectedImage = try await pickerItem?.loadTransferable(type: Image.self)
}
}
if selectedImage != nil {
selectedImage!
.resizable()
.scaledToFit()
}
}
.frame(width: 300, height: 200)
.padding()
}
}
#Preview {
ContentView()
}
Edit:
As a test I created a new app with an Image property populated with a tall, portrait JPG. That Image view displays in the correct orientation without any additional code.
However, if that same image is selected using PhotosPicker (coupled with .loadTransferable), it looses its orientation upon display.
This would indicate the issue is not with Image view itself but with the Transferable Protocol (.loadTransferable) loosing orientation, along with Image only supports PNG file types and the picker returning HEIC images from the Photos library.
Issue: Images from an ImagePicker (macOS) are displaying in landscape regardless of their actual orientation.
Desired Result: Images that are portrait should display as portrait
Steps to duplicate: Copy and paste the below code into a fresh project. Click the Select a photo button and select a picture that is portrait orientation. When it displays it will be rotated 90 degrees as landscape
Discussion: This seems to be related to the Image view object as it happens even within a PhotosPicker
Code: (import PhotosUI at top)
struct ContentView: View {
@State private var pickerItem: PhotosPickerItem?
@State private var selectedImage: Image?
var body: some View {
VStack {
PhotosPicker("Select a photo", selection: $pickerItem)
.onChange(of: pickerItem) {
Task {
selectedImage = try await pickerItem?.loadTransferable(type: Image.self)
}
}
if selectedImage != nil {
selectedImage!
.resizable()
.scaledToFit()
}
}
.frame(width: 300, height: 200)
.padding()
}
}
#Preview {
ContentView()
}
Edit:
As a test I created a new app with an Image property populated with a tall, portrait JPG. That Image view displays in the correct orientation without any additional code.
However, if that same image is selected using PhotosPicker (coupled with .loadTransferable), it looses its orientation upon display.
This would indicate the issue is not with Image view itself but with the Transferable Protocol (.loadTransferable) loosing orientation, along with Image only supports PNG file types and the picker returning HEIC images from the Photos library.
Share Improve this question edited yesterday Jay asked yesterday JayJay 35.6k19 gold badges58 silver badges85 bronze badges 2 |2 Answers
Reset to default 0What gives a photo portrait orientation is the way the phone was held when the picture was taken. That information is written into the photo's metadata. It is up to you to extract that information and compensate when you make an Image from it.
There are lots of pieces to the answer:
Image views only support PNG filetypes whereas the PhotosPicker returns HEIC images.
Populating an Image view via the Transfer protocol with Image.self looses orientation information ( per @matt answer ) so if .loadTransferable
is used with Image.self
, the orientation must be captured from the original image and the re-applied to the transferred image
Noting that Image views, if populated directly from a PNG, assets etc do work correctly without additional code - .loadTransferable
is the trouble.
@workingdogsupportUkraine answer here, led me to a more complete, macOS solution.
My solution was to create a structure that conforms to the Transferable Protocol, where data
is used which maintains the orientation. Instantiate an NSImage using that data, as this is macOS, and then creating the Image from the NSImage data, keeping the orientation. Here's the struct
struct ImageTransferable: Transferable {
let transferredImage: Image
enum TransferringError: Error {
case transferFailed
}
static var transferRepresentation: some TransferRepresentation {
DataRepresentation(importedContentType: .image) { data in
guard let nsimage = NSImage(data: data) else {
throw TransferringError.transferFailed
}
let image = Image(nsImage: nsimage)
return ImageTransferable(transferredImage: image)
}
}
}
note that I tried importedContentType: .heic
but it was inconsistent so using .image
seems better
And the implementation is
Task {
if let loaded = try await pickerItem?.loadTransferable(type: ImageTransferable.self) {
selectedImage = loaded.transferredImage
} else {
print("Image load failed")
}
}
- Win10、安卓手机实现打通:拖拽即可互传文件
- 从鼠标到触屏输入 另类角度深度分析PC进化
- 微软发布Surface平板:定义并示范Win8用户体验
- How to optimize query performance in a large fact table with billions of rows? - Stack Overflow
- c# - TrackableBehaviour.Status type is missing when using Vuforia - Stack Overflow
- gdal - Using gdal_translate to compress multiple TIFF files - Stack Overflow
- unity game engine - After commit to git, all gameobjects loose their assets - Stack Overflow
- Django is not updating on MacOS - Stack Overflow
- testing - Cypress does not load static fonts - Stack Overflow
- python - Azure Cognitive Vector search query and index creation - Stack Overflow
- c++ - Which option has precendence if I enable and disable FrontEndHeapDebugOptions at the same time? - Stack Overflow
- vba - Excel Macro to rename tabs is failing on the second run - Stack Overflow
- React Native Build Error on Windows: "EMFILE: too many open files" During `assembleRelease` - Stack Overflow
- python - Newton raphson fails to approximate beyond two decimal points - Stack Overflow
- java - Is this a bug in the JVM, or in NASM? - Stack Overflow
- python - How to optimise this simulation of a lottery? - Stack Overflow
- python - Airflow on_success_callback - Stack Overflow
.loadTransferable
withImage.self
looses orientation data so it can be used but the orientation would need to be captured from the image and then re-applied after transfer. I updated the question with a bit more info and added an answer which seems to be working - somewhat based on your answer, which I upvoted. – Jay Commented yesterday