Ios 为什么在苹果设备上解码base64文本字符串时,我会看到一个裁剪过的图像?
我有一个iOS应用程序,它从API获取一个图像作为base64编码字符串。(我知道这可能不是最好的解决方案,但这不是问题所在) 当我解码此字符串以使用以下代码创建UIImage时:Ios 为什么在苹果设备上解码base64文本字符串时,我会看到一个裁剪过的图像?,ios,objective-c,swift,macos,safari,Ios,Objective C,Swift,Macos,Safari,我有一个iOS应用程序,它从API获取一个图像作为base64编码字符串。(我知道这可能不是最好的解决方案,但这不是问题所在) 当我解码此字符串以使用以下代码创建UIImage时: // If don't don't append "=" I'll get nil data in the next line: (string.count % 4 == 0) is required let stringWithEquals:String = getMyString() + "="
// If don't don't append "=" I'll get nil data in the next line: (string.count % 4 == 0) is required
let stringWithEquals:String = getMyString() + "="
let data = Data.init(base64Encoded: stringWithEquals, options: .ignoreUnknownCharacters)!
self.myPicture.image = UIImage(data: data )
返回的图像被裁剪(我添加红色背景只是为了显影):
正如您所看到的,我收到一个错误消息,称“无法将UIImage转换为PNG”
所以在这一点上,我开始认为我的代码可能有错误。也许我得到的是一个不完整的字符串,或者是解码过程中遗漏了一些步骤。所以我问了后台人员,他确认字符串是正确的。我还与我的同事进行了核实,他在Android版本上工作,同样的字符串在他的应用程序中正常工作 因此,我在一个在线解码器中测试了这个字符串,并使用Safari 13.0.5版(15608.5.11)创建了相同的裁剪结果,但使用Firefox创建了完整图像: WTF 我在几个web解码器中测试了它,结果相同:
- 返回的解码数据不是nil。我在字符串末尾添加了“=”字符,以确保字符串长度%4==0。我发现了很多关于这个问题的问题,我能够解码图像,但被裁剪了
- 我100%确信字符串是完整的,我已经和我的后端和android同事检查过了
- 这似乎是一个与苹果环境有关的问题,我在iOS应用程序中看不到图像,在Safari中也看不到,但在Mac电脑上运行的Firefox中可以看到。而且这不仅仅发生在我的电脑上。其他一些同事在他们的iPhone上进行了测试,结果也一样
base64字符串非常长(我将在下面粘贴它)。所以我试着解码字符串的一半,只是为了确定问题与大小无关,我发现了一些古玩。如果我只解码了字符串的一半,结果也会被裁剪:
let stringWithEquals:String = getMyString().prefix(getMyString().count/2) + "="
我不知道这个近似是否正确,但我试过了
我尝试使用Objective-C函数找到解决方案,但结果是一样的:
-(NSData *)base64DataFromString: (NSString *)string{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[3];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil){
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true){
if (ixtext >= lentext){
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= 'A') && (ch <= 'Z')){
ch = ch - 'A';
}else if ((ch >= 'a') && (ch <= 'z')){
ch = ch - 'a' + 26;
}else if ((ch >= '0') && (ch <= '9')){
ch = ch - '0' + 52;
}else if (ch == '+'){
ch = 62;
}else if (ch == '='){
flendtext = true;
}else if (ch == '/'){
ch = 63;
}else{
flignore = true;
}
if (!flignore){
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext){
if (ixinbuf == 0){
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2)){
ctcharsinbuf = 1;
}else{
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4){
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++){
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak){
break;
}
}
}
return theData;
}
-(NSData*)base64DataFromString:(NSString*)string{
无符号长文本,lentext;
无符号字符ch,inbuf[4],extruf[3];
短i,ixinbuf;
布尔flignore,flendtext=false;
常量无符号字符*临时字符串;
n可变数据*数据;
如果(字符串==nil){
返回[NSData data];
}
ixtext=0;
tempcstring=(const unsigned char*)[string UTF8String];
lentext=[字符串长度];
数据=[NSMutableData dataWithCapacity:lentext];
ixinbuf=0;
while(true){
如果(ixtext>=lentext){
打破
}
ch=tempcstring[ixtext++];
flignore=false;
如果((ch>='A')&&(ch='A')&&(ch='0')&&(ch 4);
exputf[1]=((inbuf[1]&0x0F)>2);
exputf[2]=((inbuf[2]&0x03)您必须“附加”=“…这样它就可以被4整除,这是一个很好的线索。这意味着您的字符串格式不正确
如果您检查字符串的长度(您在GitHub发布的),您将看到它是65535
…这也是0xFFFF
…这也是16位
因此,听起来您的“API”没有返回完整的图像。您必须“附加”=“…这样它就可以被4整除,这是一个很好的线索。这意味着您的字符串格式不正确
如果您检查字符串的长度(您在GitHub发布的),您将看到它是65535
…这也是0xFFFF
…这也是16位
听起来像是你的“API”没有返回完整图像。但是为什么我可以在Firefox中使用相同的字符串来查看完整图像?我的意思是,我只是复制粘贴相同的字符串,然后works@Leemur-你能将你的原始图像添加到你的问题中吗?也许Safari的最大粘贴长度为65535个字符,而Firefox没有?GITHUB的DAMM字符串是截断的d、 也是。这不是完整图像的base64编码。请询问您的后端人员他的字符串是否为65535字节。但是为什么我可以在Firefox中使用相同的字符串来查看完整图像?我的意思是,我只是复制粘贴相同的字符串,并且works@Leemur-能否将原始图像添加到问题中?Safari的最大粘贴长度可能为65535个字符rs和Firefox没有?GITHUB上的DAMM字符串也被截断了。它不是完整图像的base64编码。询问后端人员他的字符串是否为65535字节。