This is a macOS app, while using Image("my file url")
in my CoverImageView
, I can export a .png
file that contains the Image("my file url")
view successfully.
However, this doesn't happen when I use Image(nsImage: NSImage(data: imageData.imagedata))
, the imageData.imagedata
is a Data type that will be gotten when I tap a button and get it from a selected picture (I will show it later in my code).
When I select an image, it can be seen in my app's View.
However, when I save this View(CoverImageView
) to a .png file it only contain the blue view, the Mac view is gone!!!!
Here is the CoverImageView
from which I want to create a .png file
struct CoverImageView: View {
@EnvironmentObject var imageData: ImageData
var body: some View {
ZStack {
Rectangle()
.frame(width: 512, height: 600)
.foregroundColor(.blue)
Image(nsImage: (NSImage(data: imageData.imagedata) ?? NSImage(byReferencing: URL(fileURLWithPath: ""))))
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 512, height: 512)
}
}
}
This is the main view PhotoTestView
struct PhotoTestView: View {
@State private var imageUrl: URL = URL(fileURLWithPath: "")
@EnvironmentObject var imageData: ImageData
var body: some View {
VStack {
CoverImageView()
Divider()
.frame(width: 1024)
HStack {
Button(action: {
if let openURL = ImageProcess().showOpenPanel() {
imageUrl = openURL
if let codedImages = try? Data(contentsOf: openURL) {
imageData.imagedata = codedImages
}
}
}, label: {
Image(systemName: "doc.badge.plus")
})
Button(action: {
ImageProcess().saveImage()
}, label: {
Image(systemName: "square.and.arrow.down")
})
}.padding()
}
}
}
The View Extension which will create a png file from a view
extension View {
func imageRepresentation(rect: CGRect) -> NSBitmapImageRep? {
let hosting = NSHostingView(rootView: self)
hosting.setFrameSize(rect.size)
hosting.setBoundsSize(rect.size)
hosting.layout()
hosting.layerContentsRedrawPolicy = .onSetNeedsDisplay
hosting.setNeedsDisplay(rect)
if let imageRepresentation = hosting.bitmapImageRepForCachingDisplay(in: rect) {
hosting.cacheDisplay(in: rect, to: imageRepresentation)
return imageRepresentation
}
return nil
}
func asImage(rect: CGRect) -> NSImage? {
if let cgImage = imageRepresentation(rect: rect)?.cgImage {
return NSImage(cgImage: cgImage, size: rect.size)
}
return nil
}
func asPngData(rect: CGRect) -> Data? {
return imageRepresentation(rect: rect)?.representation(using: .png, properties: [:])
}
}
png File Reader and Save
struct ImageProcess {
func showOpenPanel() -> URL? {
let openPanel = NSOpenPanel()
openPanel.allowedContentTypes = [.image]
openPanel.allowsMultipleSelection = false
openPanel.canChooseDirectories = false
openPanel.canChooseFiles = true
let response = openPanel.runModal()
return response == .OK ? openPanel.url : nil
}
func saveURL() -> URL? {
let savePanel = NSSavePanel()
savePanel.allowedContentTypes = [.png]
savePanel.canCreateDirectories = true
savePanel.isExtensionHidden = false
savePanel.allowsOtherFileTypes = false
savePanel.title = "Save your image"
savePanel.message = "Choose a folder and a name to store your image."
savePanel.nameFieldLabel = "File name:"
let response = savePanel.runModal()
return response == .OK ? savePanel.url : nil
}
func saveImage() {
let view = CoverImageView().environmentObject(ImageData())
let imageData = view.asPngData(rect: CGRect.init(x: 0, y: 0, width: 1024, height: 768))
if let url = saveURL() {
try? imageData!.write(to: url)
}
// print(imageData)
}
}
Could you help me?