什么时候用jpg png png转webp工具 base64

webP 格式图片在 iOS 中的应用 - 简书
下载简书移动应用
写了9763字,被63人关注,获得了76个喜欢
webP 格式图片在 iOS 中的应用
本篇来源于,它们在采用了
的图片后,网络数据传输大幅减少.
以及腾讯发布的 都可以拿出非常漂亮的数据让我们转到 webP 的怀抱(至少部分)
下面是 taobao 的优化对比图
下面是 腾讯的 图片格式对比图
可以看到有非常的实用价值,下面我们看看如何引入到具体项目中
webp 在 iOS中 的应用
本地采用 webP 图片
下载第三方库
很幸运,SDWebImage里面有个webP 框架,可以将webp--&NSData--&UIImage最后变为可识别的图片格式直接给控件调用
但是我在上看见了下面这段话
There are 3 subspecs available now: Core, MapKit and WebP (this means you can install only some of the SDWebImage modules. By default, you get just Core, so if you need WebP, you need to specify it).
Podfile example:
$pod 'SDWebImage/WebP'
也就是说我们需要额外下载这个webP库,注意,这个会从 google 下载,如果失败,开 VPN 试试,下载完成后,文件结构如下
SDWebImage 的源码如下,我们直接使用转化出的 UIImage 即可
#ifdef SD_WEBP
#import &UIKit/UIKit.h&
// Fix for issue #416 Undefined symbols for architecture armv7 since WebP introduction when deploying to device
void WebPInitPremultiplyNEON(void);
void WebPInitUpsamplersNEON(void);
void VP8DspInitNEON(void);
@interface UIImage (WebP)
+ (UIImage *)sd_imageWithWebPData:(NSData *)
据了解,还有部分三方库也可以...但是我没有进行研究了,我觉得原理应该都差不多,下面重点要说的是和 taobao 一样,如何在 webView 和网络传输中如何使用webp
在 webView 中实用 webP
先给一个 webP 测试 html:
html 的代码如下
&meta charset="utf-8"&
&meta http-equiv="X-UA-Compatible" content="IE=edge"&
&meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"&
&title&webp&/title&
&img src="http://testing.yongche.org/images/150X1501.webp” width = 50 ,height = 20&
![](http://testing.yongche.org/images/150X1501.webp)
第一个办法 和 JS 协作
webView 等网页上如果用的是 webP 图片,iOS 直接解析的话,会显示?图片.
后来决定这么搞:
A. 在网页加载出后截取到 HTML 及内部的 JS 后,调用 JS 预先准备好的方法获取需要转码的 webP 格式图片下载地址(其实一个一个的遍历也行).B. 在App 本地开启线程下载图片,下载完成后,将图片转码由 webP—& png—&Base64(因为实验出直接用 png/jpg 的话 没用)C. 将 Base64及原图片下载地址一一对应调用 JS 准备好的方法进行替换D. 将下载后的图片进行缓存,并进行管理
注意点:A. 图片在最终显示成功前会显示成?,此处为了用户体验应该采用占位图片B. 图片显示成功前应该保持网页布局不调整,需要由 JS 预先设置好布局C. 图片在本地的缓存需要管理
相应的,HTML需要更改代码,如下
&meta charset="utf-8"&
&meta http-equiv="X-UA-Compatible" content="IE=edge"&
&meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"&
&title&webp&/title&
&script type="text/javascript"&
var YongChe = {};
YongChe.getAllWebPImg = function() {
var images = document.getElementsByTagName('img');
var srcList = [];
var patt1 = new RegExp("\.webp$");
for(var i = 0; i & images. i++) {
if(patt1.test(images[i].src)) {
srcList.push(images[i].src);
console.log(srcList);
return JSON.stringify(srcList);
YongChe.replaceWebPImg = function(src, localPath) {
alert(localPath);
elementList = document.querySelectorAll('img[src="'+src+'"]');
console.log(elementList);
for(element in elementList) {
elementList[element].src = localP
&img src="http://testing.yongche.org/images/150X1501.webp” width = 50 ,height = 20&
![](http://testing.yongche.org/images/150X1501.webp)
&script type="text/javascript"&
console.log(YongChe.getAllWebPImg());
YongChe.replaceWebPImg('http://testing.yongche.org/images/logo.png','http://testing.yongche.org/images/150X1501.webp')
App本地也需要做出相应的措施
//在 `webView` 加载完 `HTML` 后,解析源码,执行相应的 `JS` 方法
-(void)webViewDidFinishLoad:(UIWebView *)webView
//获取`HTML`代码
NSString *lJs = @"document.documentElement.innerHTML";
NSString *str = [webView stringByEvaluatingJavaScriptFromString:lJs];
//执行约定好的方法,获取需要下载的 webp 图片
NSString *imgs = [self.webView stringByEvaluatingJavaScriptFromString:@"YongChe.getAllWebPImg();"];
NSArray *array = [NSJSONSerialization JSONObjectWithData:[imgs dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
//此处,做示范,只转换第一个,将图片下载下来,并且转为 PNG 后,再转成 Base64,传给 JS 脚本执行
NSString *imgUrl = array.firstO
__weak typeof (self) weakSelf =
[SDWebImageCustomeDownLoad downloadWithURL:[NSURL URLWithString:imgUrl] progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSString *base = [NSString stringWithFormat:@"data:image/base64,%@",imgBase];
NSString *js = [NSString stringWithFormat:@"YongChe.replaceWebPImg('%@','%@')",imageURL,base];
[weakSelf.webView stringByEvaluatingJavaScriptFromString:js];
下面这个方法是修改 SDWebImage 自带的,本来是属于 UIImage的分类方法,此处只是提取出下载这个操作,并没有深入更改,大家别介意
+ (void)downloadWithURL:(NSURL *)url progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock
[self sd_cancelCurrentImageLoad];
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (url) {
__weak __typeof(self)wself =
id &SDWebImageOperation& operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:0 progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (!wself)
dispatch_main_sync_safe(^{
if (!wself)
if (image && completedBlock)
completedBlock(image, error, cacheType, url);
else if (image) {
//没有回调,但是图片下载完成了
//image 下载失败
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
//这一步,将这个 View 之前的下载操作全部取消,然后将这次的操作放进去
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
dispatch_main_async_safe(^{
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
if (completedBlock) {
completedBlock(nil, error, SDImageCacheTypeNone, url);
只能说成功了,但是看着效果明显很龊,下面说说其他办法
第二种办法 NSURLProtocol
采用 webP 的目的就是减少网络传输数据量,加快请求整体速度,现在的问题就在于 webView 不识别 webP 这种格式而已,再想想 iOS内的所有网络请求/响应我们都可以控制,那我们获取到数据时,转化成它识别的给它就可以了,而可以帮我们在拿到数据时进行某些操作,操作完以后又正常进行网络流程的,就是接下来的主角了 --- NSURLProtocol,如果大家和我一样平时用的少的话,可以看看 JamesYu 的这篇简书
再看 taobao 前辈们的说法:
估计也是这样做的, OK. 那开撸
NSURLProtocol
自定义一个 YCCustomURLProtocol 继承自 NSURLProtocol
#import &Foundation/Foundation.h&
@interface YCCustomURLProtocol : NSURLProtocol
在 delegate 注册下这个协议
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//注册protocol
[NSURLProtocol registerClass:[CustomURLProtocol class]];
return YES;
实现协议内容
有几个注意点:
NSURLConnection 活跃的iOS版本,NSURLSession 可以酌情代替之
不论 NSURLConnection 还是 NSURLSession,尽量把 URLProtocol didFailWithError URLProtocol DidFinishLoading URLProtocol didLoadData URLProtocol didReceiveResponse 几个方法写全,避免网络请求产生不可预知的 BUG
暂时就这些
NSURLConnection
#import "YCCustomURLProtocol.h"
#import "UIImage+WebP.h"
static NSString *URLProtocolHandledKey = @"URLHasHandle";
@interface YCCustomURLProtocol()&NSURLSessionDelegate,NSURLSessionDataDelegate&
@property (nonatomic,strong) NSURLConnection *
@implementation YCCustomURLProtocol
#pragma mark 初始化请求
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
//只处理http和https请求
NSString *scheme = [[request URL] scheme];
if ( ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame))
//看看是否已经处理过了,防止无限循环
if ([NSURLProtocol propertyForKey:URLProtocolHandledKey inRequest:request]) {
return NO;
return YES;
return NO;
+ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {
#pragma mark 通信协议内容实现
- (void)startLoading
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
//标示改request已经处理过了,防止无限循环
[NSURLProtocol setProperty:@YES forKey:URLProtocolHandledKey inRequest:mutableReqeust];
if (![[self.request.URL absoluteString] hasSuffix:@"webp"]) {
NSLog(@"正常请求,让它 goon ");
NSLog(@"检测到了 webp---%@,拦截它",self.request.URL);
self.connection = [NSURLConnection connectionWithRequest:mutableReqeust delegate:self];
- (void)stopLoading
[self.connection cancel];
#pragma mark 请求管理 connection
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if ([connection.currentRequest.URL.absoluteString hasSuffix:@"webp"]) {
NSLog(@"webp---%@---替换它",connection);
UIImage *imgData = [UIImage sd_imageWithWebPData:data];
NSData *jpgData = UIImageJPEGRepresentation(imgData, 1.0f);
[self.client URLProtocol:self didLoadData:jpgData];
[self.client URLProtocol:self didLoadData:data];
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
[self.client URLProtocolDidFinishLoading:self];
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[self.client URLProtocol:self didFailWithError:error];
NSURLSession
#import "YCCustomURLProtocol.h"
#import "UIImage+WebP.h"
static NSString *URLProtocolHandledKey = @"URLHasHandle";
@interface YCCustomURLProtocol()&NSURLSessionDelegate,NSURLSessionDataDelegate&
@property (nonatomic,strong) NSURLSession *
@implementation YCCustomURLProtocol
#pragma mark 初始化请求
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
//只处理http和https请求
NSString *scheme = [[request URL] scheme];
if ( ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame))
//看看是否已经处理过了,防止无限循环
if ([NSURLProtocol propertyForKey:URLProtocolHandledKey inRequest:request]) {
return NO;
return YES;
return NO;
+ (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {
#pragma mark 通信协议内容实现
- (void)startLoading
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
//标示改request已经处理过了,防止无限循环
[NSURLProtocol setProperty:@YES forKey:URLProtocolHandledKey inRequest:mutableReqeust];
if (![[self.request.URL absoluteString] hasSuffix:@"webp"]) {
NSLog(@"是一个正常的,%@",self.request.URL);
NSLog(@"检测到了 webp---%@,拦截它",self.request.URL);
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue currentQueue]];
[[self.session dataTaskWithRequest:mutableReqeust] resume];
- (void)stopLoading
[self.session invalidateAndCancel];
#pragma mark dataDelegate
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
if (completionHandler) {
completionHandler(NSURLSessionResponseAllow);
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
NSData *transData =
if ([dataTask.currentRequest.URL.absoluteString hasSuffix:@"webp"]) {
NSLog(@"webp---%@---替换它",dataTask.currentRequest.URL);
//采用 SDWebImage 的转换方法
UIImage *imgData = [UIImage sd_imageWithWebPData:data];
transData = UIImageJPEGRepresentation(imgData, 1.0f);
[self.client URLProtocol:self didLoadData:transData];
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error{
if (error) {
[self.client URLProtocol:self didFailWithError:error];
[self.client URLProtocolDidFinishLoading:self];
ok, 至此已经全部成功,不过 NSURLProtocol 会影响 App 内所有请求,稍有遗漏的话后果比较严重,大家一定要慎重.不过相比效果,电商类 App 采用大量图片的话还是值得转换到 webP 阵营的
谢谢观看,个人水平有限,如有遗漏/不妥,请指出
PS:原创文章,转载请注明地址:
若对您有帮助,那么你轻轻点一下喜欢,将是对我莫大的鼓励~?
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
专题内容主要包括OC、swift等涉及到iOS开发进阶的内容。
swift可以关注下我的另一个专题:
swift开发...
· 13513人关注
· 3452人关注
心情不好的时候问自己 :
我为何这么屌
心情好的时候问自己 : 为什么比我屌的这么多
· 2896人关注
若对您有帮助,那么你轻轻点一下喜欢,将是对我莫大的鼓励~?
选择支付方式:svg、jpg、png、webp以及bpg各自的应用场景和优缺点是怎样的?你的应用选择了哪些格式,为什么?
按时间排序
只说自己的码农工作,iOS和Android开发,其它场景不知道。svg拿来缩小软件大小,或者直接将svg转为代码运行。png是标志的贴图格式,拿来做一般的按钮啊列表背景啊,一般切好的图都是png。jpg是相对较大的图片,大图片的话png尺寸太大,即使有损压缩也未必比jpg好,所以图片大到一定程度就用jpg了。webp实在太烦人,找第三方库(别问我为啥不自己做解码,号称码农,实则码弱)表现不一,在没有像样的解码库之前,没法像png,jpg那样简单美好。gif用过,自己玩玩,但没在实际项目中用,大批gif图片的时候资源占用太大,其它没感觉。其它格式完全没有碰过,不评价。
在安卓 QQ 聊天信息流里的那些图片就是 webp 格式。
已有帐号?
无法登录?
社交帐号登录Convert picture to base64 - Picbase64
convert picture to base64
UPLOAD A PICTURE TO CONVERT TO BASE64
With CSS & HTML
Example with div tag
&html&&head&&style type="text/css"&
.class_example{background-image: url(data:image/base64,iVBORw......);width: ... height: ...}
&/style&&/head&
&div class="class_example"&&/div&
&/body&&/html&
Dimensions (width x height px) of picture have to be added into CSS in order to display picture into div.
Example with body tag
&html&&head&&style type="text/css"&
body{ background-image:url(data:image/base64,iVBORw......);background-repeat:}&/style&&/head&
You can use background repeat property with base 64 data and get a background that will be repeated.
(online tool to convert picture to base 64) - Beta V0.2 -

我要回帖

更多关于 png转webp工具 的文章

 

随机推荐