最近在做项目,需求就是要传尽量多的数据,属于一个调研,估计后期会加入到项目里面,二维码其实不推荐放入大量数据,但是需求嘛,拿钱干活,可能后期还会优化,因为目前的画扫描的效率不高,主要直接用的原生的开源库zxing感觉效率不高。
一开始,从数据源下手,进行数据源压缩,首先尝试了hufman编码,huffman主要是一些开源的算法,但是实现从建树到压缩,其实有很大区别,文件我直接上传了,有兴趣的可以看一下:
http://download.csdn.net/detail/shidongdong2012/7354863
我发现这种压缩效率并不高,接着我采用了gzip+base64的组合方式,发现效果比较号:
首先在因为gzip压缩要用到zlib,所以我们要在工程里面加libz.dylib,
然后附上实现gzip的压缩实现:
h文件
#import <Foundation/Foundation.h> @interface NSData (GZIP) - (NSData *)gzippedDataWithCompressionLevel:(float)level; - (NSData *)gzippedData; - (NSData *)gunzippedData; @end
- (NSData *)gzippedDataWithCompressionLevel:(float)level
{
if ([self length])
{
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.avail_in = (uint)[self length];
stream.next_in = (Bytef *)[self bytes];
stream.total_out = 0;
stream.avail_out = 0;
int compression = (level < 0.0f)? Z_DEFAULT_COMPRESSION: (int)(roundf(level * 9));
if (deflateInit2(&stream, compression, Z_DEFLATED, 31, 8, Z_DEFAULT_STRATEGY) == Z_OK)
{
NSMutableData *data = [NSMutableData dataWithLength:ChunkSize];
while (stream.avail_out == 0)
{
if (stream.total_out >= [data length])
{
data.length += ChunkSize;
}
stream.next_out = (uint8_t *)[data mutableBytes] + stream.total_out;
stream.avail_out = (uInt)([data length] - stream.total_out);
deflate(&stream, Z_FINISH);
}
deflateEnd(&stream);
data.length = stream.total_out;
return data;
}
}
return nil;
}
- (NSData *)gzippedData
{
return [self gzippedDataWithCompressionLevel:-1.0f];
}
- (NSData *)gunzippedData
{
if ([self length])
{
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.avail_in = (uint)[self length];
stream.next_in = (Bytef *)[self bytes];
stream.total_out = 0;
stream.avail_out = 0;
NSMutableData *data = [NSMutableData dataWithLength:(NSUInteger)([self length] * 1.5)];
if (inflateInit2(&stream, 47) == Z_OK)
{
int status = Z_OK;
while (status == Z_OK)
{
if (stream.total_out >= [data length])
{
data.length += [self length] * 0.5;
}
stream.next_out = (uint8_t *)[data mutableBytes] + stream.total_out;
stream.avail_out = (uInt)([data length] - stream.total_out);
status = inflate (&stream, Z_SYNC_FLUSH);
}
if (inflateEnd(&stream) == Z_OK)
{
if (status == Z_STREAM_END)
{
data.length = stream.total_out;
return data;
}
}
}
}
return nil;
}
让我们看一下压缩实现:
NSData * data = [resultStr dataUsingEncoding:NSUTF8StringEncoding];
NSData * compressData = [data gzippedData];
NSString * rstring = [compressData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];看看如果扫描到结果怎么处理吧:
NSData * data = [[NSData alloc] initWithBase64EncodedString:[result text] options:NSDataBase64Encoding64CharacterLineLength];
NSString * str = [[NSString alloc] initWithData:[data gunzippedData] encoding:NSUTF8StringEncoding];原文:http://blog.csdn.net/shidongdong2012/article/details/25955689