上传图片到服务器时出现绿线
Posted
技术标签:
【中文标题】上传图片到服务器时出现绿线【英文标题】:Green lines appeared when uploading an image to server 【发布时间】:2020-09-22 03:07:25 【问题描述】:我有一个 ios 应用程序,它允许使用下面的 Swift 函数将图像上传到 Ubuntu 服务器(带有 Apache 网络服务器):
private func uploadPhoto(image:UIImage)
let imageData = image.jpegData(compressionQuality: 0.6)
if imageData == nil
NSLog("Image Data is nil")
else
let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
let url = URL(string: "https://example.com/myapi.php")!
var request = URLRequest(url: url)
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
let boundary = NSUUID().uuidString
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
// Text Parameter: Action
body.append(NSString(format: "--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Disposition: form-data; name=\"action\"\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "some_text_data\r\n").data(using: String.Encoding.utf8.rawValue)!)
// Text Parameter: Build Number
body.append(NSString(format: "--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Disposition: form-data; name=\"build\"\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: ("\(buildNumber ?? "99999")\r\n" as NSString)).data(using: String.Encoding.utf8.rawValue)!)
// File Parameter
body.append(NSString(format: "--%@\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format:"Content-Disposition: form-data; name=\"the_img\"; filename=\"image.jpg\"\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(NSString(format: "Content-Type: application/octet-stream\r\n\r\n").data(using: String.Encoding.utf8.rawValue)!)
body.append(imageData!)
body.append(NSString(format: "\r\n--%@--\r\n", boundary).data(using: String.Encoding.utf8.rawValue)!)
request.httpBody = body as Data
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: data, response, error in
guard error == nil else
return
guard let data = data else
return
do
//create json object from data
if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any]
print(json)
catch let error
print(error.localizedDescription)
)
task.resume()
上传功能正常,图片上传到服务器没有错误。但是,某些上传的图片(大约 100 张图片中的 1 张)会在上传图片的缩略图(在 macOS 10.15.6 Finder 的快速预览中显示)上有绿线; JPEG似乎已损坏。请参阅下面的示例屏幕截图:
但是图片本身好像没有问题:
为什么会这样?如果image.jpegData(compressionQuality:)
设置为1.0
(无压缩),则根本不会发生此问题。我的图片压缩有误吗?
【问题讨论】:
我不明白。如果图像从 iOS 应用程序上传到 Ubuntu 服务器,您如何“在 macOS 10.15.6 Finder 的快速预览中”查看它们的缩略图? 我将图像从 Ubuntu 服务器下载到我的桌面 iMac。 【参考方案1】:您需要检查图像的整个流程,看看到底发生了这种损坏。
根据您发布的内容,您有一个UIImage
,它是图像的内存表示。您声称这张图片看起来不错。
下一步是使用image.jpegData(compressionQuality: 0.6)
将图像编码为标准格式的JPEG。结果是可写入文件的数据,并且可以由许多支持打开 JPEG 图像的应用程序中的任何一个打开。我建议您尝试将其写入某个文件(Data
具有使用FileManager.default
的写入选项),或者您可以快速尝试使用activity controller 直接将其发送到您的计算机。
如果此步骤产生损坏的图像,则 iOS 上的编码器存在问题,我希望不是这种情况。但如果是这样,请提交错误报告并尝试使用不同的压缩质量或不同的格式(如果可能,PNG)。
在这部分之后,您将原始 JPEG 数据注入到 HTTP 请求的正文中。它没有什么特别之处。数据应该按原样传送到服务器,并且在传输过程中发生损坏的机会太接近于零,以至于无法在一生中见证损坏。所以在这部分之后你需要检查服务器上发生了什么。
如果服务器上没有发生任何事情,那么下载您的 JPEG 应该会产生与您发送到服务器的数据完全相同的数据。您可以通过将您的数据imageData
与下载的数据进行比较来检查这一点(只需使用try! Data(contentsOf: URL(string: "your URL here")!)
)。
如果数据不一样(我现在预计会这样),您应该分析服务器端发生的情况。发生这种损坏似乎很奇怪,但可能存在一些不兼容的设置。有时解决方案非常不直观;例如,您还需要在请求中发送 mime 类型。我认为在你的情况下应该是image/jpeg
。
此外,从我们看到的异常情况来看,我怀疑“每行字节数”存在兼容性问题。有时出于性能原因,在每个“行”的末尾添加额外的填充。如果不忽略填充,则将其带到下一行。在您损坏的图像中,您可以看到第一行正常,而第二行以绿色异常开始。第三行将异常向前移动另一个相等的长度。不确定这些信息是否对您有任何帮助,但这是处理图形纹理时的常见问题,例如在使用 openGL 时。
【讨论】:
感谢您的详细回答。我想我应该马上开始我的调试之旅。似乎很难调试这个。 我对回答致以最深的敬意;虽然想指出第一行也不好 - 黄色“射线”从那里开始(从瓶子的顶部)。并且整个图像的颜色都混乱了。无论如何,所描述的确定错误的方法是我能想象到的最好的方法 @nrx 你是对的,谢谢。我确实看到还有多个其他异常;黄色,然后是一些蓝色和一些红色伪影。造成它们的原因真的超出了我的范围。但如果我不得不猜测,我会说这是压缩质量的一部分。由于压缩将块打包在一起,因此假设单个“像素”错误会影响整个区域是有意义的。我们甚至可以观察到两条绿线周围的一些伪影对称。但同样,这只是我的猜测。【参考方案2】:我首先将 mime 类型从 application/octet-stream
更改为 image/jpeg
(正如 Matic Oblak 在他的详细回答中所建议的那样)。
因此,我自己在上传图片时遇到了问题。
【讨论】:
以上是关于上传图片到服务器时出现绿线的主要内容,如果未能解决你的问题,请参考以下文章