在 Swift 中将图像保存到相机胶卷时出现问题

问题描述 投票:0回答:1

我正在尝试使用

ContentMenu
来允许用户执行诸如将图像保存到相机胶卷等操作。目前在代码中,显示图像的值是
Image
类型,所以我创建了一个函数,应该将其转换为
UIImage
类型的值,然后图像将通过
UIImageWriteToSavedPhotosAlbum()
保存到相机胶卷中。该代码有效,但是当我查看相机胶卷中保存的图像时,它显示为全黑图像,而不是实际图像本身。

转换的代码如下:

extension Image {
    func asUIImage() -> UIImage? {
        // Create a UIView
        let uiView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        
        // Create a hosting controller with the SwiftUI Image
        let hostingController = UIHostingController(rootView: self)
        
        // Assign the frame to the hosting controller
        hostingController.view.frame = uiView.bounds
        
        // Add the hosting controller's view to the UIView
        uiView.addSubview(hostingController.view)
        
        // Make the snapshot of the hosting controller's view
        UIGraphicsBeginImageContextWithOptions(uiView.bounds.size, uiView.isOpaque, 0.0)
        defer { UIGraphicsEndImageContext() }
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        uiView.layer.render(in: context)
        let uiImage = UIGraphicsGetImageFromCurrentImageContext()
        
        return uiImage
    }
}

这里称为:

func manyMediaView(media: [MediaOBJ]) -> some View {
        GeometryReader { geo in
            TabView {
                ForEach(media.indices, id: \.self) { index in
                    AsyncImage(url: media[index].link) { phase in
                        switch phase {
                        case .success(let image):
                            image
                                .resizable()
                                .aspectRatio(contentMode: .fill)
                                .contentShape(Rectangle())
                                .onTapGesture {
                                    selectedImageIndex = index
                                    showFullImage = true
                                }
                                .contextMenu {
                                    Button(action: {
                                        // Action to copy the photo
                                    }) {
                                        Text("Copy Photo")
                                        Image(systemName: "doc.on.doc")
                                    }
                                    
                                    Button(action: {
                                        // Action to save the photo
                                        if let uiImage = image.asUIImage() {
                                            UIImageWriteToSavedPhotosAlbum(uiImage, nil, nil, nil)
                                            print("Saved successfully!")
                                        } else {
                                            print("Error: Unable to convert Image to UIImage.")
                                        }
                                    }) {
                                        Text("Save Photo")
                                        Image(systemName: "square.and.arrow.down")
                                    }
                                    
                                    ShareLink(item: viewModel.post.url) {
                                        Text("Share via ...")
                                        Image(systemName: "square.and.arrow.up")
                                    }
                                }
                        case .failure:
                            DefaultPlaceholder()
                                .maxHeight(600)
                                .onAppear {
                                    imageLoadKey = .init()
                                }
                        case .empty:
                            Color.clear
                        }
                    }
                    .tag(index)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                }
            }
            .cornerRadius(16)
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
            .indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))
            .gesture(
                DragGesture().onChanged { value in
                    if value.translation.width > 50 {
                        selectedImageIndex = max(selectedImageIndex - 1, 0)
                    } else if value.translation.width < -50 {
                        selectedImageIndex = min(selectedImageIndex + 1, media.count - 1)
                    }
                }
            )
            .fullScreenCover(isPresented: $showFullImage) {
                MultiImageGalleryView(imageUrls: media.map { $0.link }, isPresented: $showFullImage, selectedImageIndex: $selectedImageIndex)
            }
            .onTapGesture {
                // Intentionally empty to prevent auto navigation to SinglePostView
            }
        }
    }

我缺少什么才能正确保存图像?

ios swift swiftui uikit
1个回答
0
投票

更新:我找到了解决方案。该功能仅正确渲染大小,而不渲染内容本身。它只是用原始图像的大小制作一个新的空白

UIImage

这是修改后的正确函数:

extension Image {
    func asUIImage() -> UIImage? {
        // Create a hosting controller with the SwiftUI Image
        let hostingController = UIHostingController(rootView: self)
        
        // Calculate the size needed for rendering
        let size = hostingController.sizeThatFits(in: UIScreen.main.bounds.size)
        
        // Set the size for the hosting controller's view
        hostingController.view.bounds = CGRect(origin: .zero, size: size)
        
        // Render the hosting controller's view into an image
        let renderer = UIGraphicsImageRenderer(size: size)
        let image = renderer.image { context in
            hostingController.view.drawHierarchy(in: hostingController.view.bounds, afterScreenUpdates: true)
        }
        
        return image
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.