如何将图像转换为位图并使用 Alamofire 上传?
How to convert Image to Bitmap and upload with Alamofire?
我想通过将数据附加到请求正文来使用 Alamofire 将数据和图像发送到我的数据库。现在我已经成功插入了所有数据,但没有插入图像(图像没有插入到数据库中)。图片来自.photoLibrary
或.camera
,然后将其转换为位图字符串数据,然后将图片发送到服务器。如何使用alamofire将转换后的位图图像插入数据库?
这是我的 ContentView
import SwiftUI
import UIKit
import Alamofire
import MobileCoreServices
struct ContentView: View {
@State var chassisNumber = ""
@State var engineNumber = ""
@State var lisencePlate = ""
@State var carYear = ""
@State var carModel = ""
@State var vehiclePicture = ""
@State var imageSelected: UIImage
@State var sourceType: UIImagePickerController.SourceType = .camera
@State var showImagePicker = false
@AppStorage("userEmail") var currentUserEmail: String?
var body: some View {
VStack{
Button(action: {
sourceType = UIImagePickerController.SourceType.photoLibrary
self.showImagePicker = true
}, label: {
Text("Choose Image")
})
TextField("Car Model", text: $carModel)
TextField("Car Year", text: $carYear)
TextField("Chassis Number", text: $chassisNumber)
TextField("Engine Number", text: $engineNumber)
TextField("Lisence Plate", text: $lisencePlate)
Button(action: {
vehiclePicture = randomString(length: 25)
insertNewVehicle(EMAIL: currentUserEmail ?? "Empty", NAMA_MODEL: carModel, TAHUN_PRODUKSI: carYear, CHASSISNO: chassisNumber, ENGINENO: engineNumber, NOPOL: lisencePlate, VEHICLE_PICTURE: vehiclePicture, ENCODED_IMG: imageSelected)
}, label: {Text("Save"})
}
.sheet(isPresented: $showImagePicker){
ImagePicker(imageSelected: $imageSelected, sourceType: $sourceType)
}
}
}
func insertNewVehicle(EMAIL: String, NAMA_MODEL: String, TAHUN_PRODUKSI: String, CHASSISNO: String, ENGINENO: String, NOPOL: String, VEHICLE_PICTURE: String, ENCODED_IMG: UIImage?){
let parameters = ["EMAIL": EMAIL, "NAMA_MODEL": NAMA_MODEL, "TAHUN_PRODUKSI": TAHUN_PRODUKSI, "CHASSISNO": CHASSISNO, "ENGINENO": ENGINENO, "NOPOL": NOPOL, "VEHICLE_PICTURE": VEHICLE_PICTURE]
AF.upload(multipartFormData: { multipartFormData in
for (key,value) in parameters {
multipartFormData.append((value).data(using: .utf8)!, withName: key)
}
// Upload image to server << image is not inserted
guard let image = ENCODED_IMG else { return }
let jpegData = image.toJpegData(compressionQuality: 0.4)
multipartFormData.append(Data((jpegData)!), withName: "ENCODED_IMG")
}, to: "http://myapi")
.responseJSON { response in
// Check whether chassis number is exist or not
if let data = response.data, let string = String(data: data, encoding: .utf8){
// If chassis number is exist
print(string)
}else{
// If chassis number is not exist
print("Chassis not exists, inserting data...")
}
}
}
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
我从这里得到了 convertToJpegData
extension UIImage {
func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
guard cgImage != nil else { return nil }
let options: NSDictionary = [
kCGImagePropertyOrientation: orientation,
kCGImagePropertyHasAlpha: hasAlpha,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
return toData(options: options, type: .jpeg)
}
func toData (options: NSDictionary, type: ImageType) -> Data? {
guard cgImage != nil else { return nil }
return toData(options: options, type: type.value)
}
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
func toData (options: NSDictionary, type: CFString) -> Data? {
guard let cgImage = cgImage else { return nil }
return autoreleasepool { () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
}
}
// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
enum ImageType {
case image // abstract image data
case jpeg // JPEG image
case jpeg2000 // JPEG-2000 image
case tiff // TIFF image
case pict // Quickdraw PICT format
case gif // GIF image
case png // PNG image
case quickTimeImage // QuickTime image format (OSType 'qtif')
case appleICNS // Apple icon data
case bmp // Windows bitmap
case ico // Windows icon data
case rawImage // base type for raw image data (.raw)
case scalableVectorGraphics // SVG image
case livePhoto // Live Photo
var value: CFString {
switch self {
case .image: return kUTTypeImage
case .jpeg: return kUTTypeJPEG
case .jpeg2000: return kUTTypeJPEG2000
case .tiff: return kUTTypeTIFF
case .pict: return kUTTypePICT
case .gif: return kUTTypeGIF
case .png: return kUTTypePNG
case .quickTimeImage: return kUTTypeQuickTimeImage
case .appleICNS: return kUTTypeAppleICNS
case .bmp: return kUTTypeBMP
case .ico: return kUTTypeICO
case .rawImage: return kUTTypeRawImage
case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
case .livePhoto: return kUTTypeLivePhoto
}
}
}
}
如果您期望成功时出现空响应,则服务器需要 return 适当的 204 / 205 响应,或者您需要告诉您的响应处理程序允许您执行任何代码 return 为空 body。例如,如果您收到 200:
.responseJSON(emptyResponseCodes: [200, 204, 205]) { response in
}
好的,我终于找到了答案。我不能使用数据插入我的图像,而是我必须再次将它转换为字符串以便 post 它到服务器。
let imageData: Data = imageSelected.jpegData(compressionQuality: 0.4) ?? Data()
let encodedImage: String = imageData.base64EncodedString()
感谢大家的帮助!
我想通过将数据附加到请求正文来使用 Alamofire 将数据和图像发送到我的数据库。现在我已经成功插入了所有数据,但没有插入图像(图像没有插入到数据库中)。图片来自.photoLibrary
或.camera
,然后将其转换为位图字符串数据,然后将图片发送到服务器。如何使用alamofire将转换后的位图图像插入数据库?
这是我的 ContentView
import SwiftUI
import UIKit
import Alamofire
import MobileCoreServices
struct ContentView: View {
@State var chassisNumber = ""
@State var engineNumber = ""
@State var lisencePlate = ""
@State var carYear = ""
@State var carModel = ""
@State var vehiclePicture = ""
@State var imageSelected: UIImage
@State var sourceType: UIImagePickerController.SourceType = .camera
@State var showImagePicker = false
@AppStorage("userEmail") var currentUserEmail: String?
var body: some View {
VStack{
Button(action: {
sourceType = UIImagePickerController.SourceType.photoLibrary
self.showImagePicker = true
}, label: {
Text("Choose Image")
})
TextField("Car Model", text: $carModel)
TextField("Car Year", text: $carYear)
TextField("Chassis Number", text: $chassisNumber)
TextField("Engine Number", text: $engineNumber)
TextField("Lisence Plate", text: $lisencePlate)
Button(action: {
vehiclePicture = randomString(length: 25)
insertNewVehicle(EMAIL: currentUserEmail ?? "Empty", NAMA_MODEL: carModel, TAHUN_PRODUKSI: carYear, CHASSISNO: chassisNumber, ENGINENO: engineNumber, NOPOL: lisencePlate, VEHICLE_PICTURE: vehiclePicture, ENCODED_IMG: imageSelected)
}, label: {Text("Save"})
}
.sheet(isPresented: $showImagePicker){
ImagePicker(imageSelected: $imageSelected, sourceType: $sourceType)
}
}
}
func insertNewVehicle(EMAIL: String, NAMA_MODEL: String, TAHUN_PRODUKSI: String, CHASSISNO: String, ENGINENO: String, NOPOL: String, VEHICLE_PICTURE: String, ENCODED_IMG: UIImage?){
let parameters = ["EMAIL": EMAIL, "NAMA_MODEL": NAMA_MODEL, "TAHUN_PRODUKSI": TAHUN_PRODUKSI, "CHASSISNO": CHASSISNO, "ENGINENO": ENGINENO, "NOPOL": NOPOL, "VEHICLE_PICTURE": VEHICLE_PICTURE]
AF.upload(multipartFormData: { multipartFormData in
for (key,value) in parameters {
multipartFormData.append((value).data(using: .utf8)!, withName: key)
}
// Upload image to server << image is not inserted
guard let image = ENCODED_IMG else { return }
let jpegData = image.toJpegData(compressionQuality: 0.4)
multipartFormData.append(Data((jpegData)!), withName: "ENCODED_IMG")
}, to: "http://myapi")
.responseJSON { response in
// Check whether chassis number is exist or not
if let data = response.data, let string = String(data: data, encoding: .utf8){
// If chassis number is exist
print(string)
}else{
// If chassis number is not exist
print("Chassis not exists, inserting data...")
}
}
}
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
我从这里得到了 convertToJpegData
extension UIImage {
func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
guard cgImage != nil else { return nil }
let options: NSDictionary = [
kCGImagePropertyOrientation: orientation,
kCGImagePropertyHasAlpha: hasAlpha,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
return toData(options: options, type: .jpeg)
}
func toData (options: NSDictionary, type: ImageType) -> Data? {
guard cgImage != nil else { return nil }
return toData(options: options, type: type.value)
}
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
func toData (options: NSDictionary, type: CFString) -> Data? {
guard let cgImage = cgImage else { return nil }
return autoreleasepool { () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
}
}
// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
enum ImageType {
case image // abstract image data
case jpeg // JPEG image
case jpeg2000 // JPEG-2000 image
case tiff // TIFF image
case pict // Quickdraw PICT format
case gif // GIF image
case png // PNG image
case quickTimeImage // QuickTime image format (OSType 'qtif')
case appleICNS // Apple icon data
case bmp // Windows bitmap
case ico // Windows icon data
case rawImage // base type for raw image data (.raw)
case scalableVectorGraphics // SVG image
case livePhoto // Live Photo
var value: CFString {
switch self {
case .image: return kUTTypeImage
case .jpeg: return kUTTypeJPEG
case .jpeg2000: return kUTTypeJPEG2000
case .tiff: return kUTTypeTIFF
case .pict: return kUTTypePICT
case .gif: return kUTTypeGIF
case .png: return kUTTypePNG
case .quickTimeImage: return kUTTypeQuickTimeImage
case .appleICNS: return kUTTypeAppleICNS
case .bmp: return kUTTypeBMP
case .ico: return kUTTypeICO
case .rawImage: return kUTTypeRawImage
case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
case .livePhoto: return kUTTypeLivePhoto
}
}
}
}
如果您期望成功时出现空响应,则服务器需要 return 适当的 204 / 205 响应,或者您需要告诉您的响应处理程序允许您执行任何代码 return 为空 body。例如,如果您收到 200:
.responseJSON(emptyResponseCodes: [200, 204, 205]) { response in
}
好的,我终于找到了答案。我不能使用数据插入我的图像,而是我必须再次将它转换为字符串以便 post 它到服务器。
let imageData: Data = imageSelected.jpegData(compressionQuality: 0.4) ?? Data()
let encodedImage: String = imageData.base64EncodedString()
感谢大家的帮助!