iPhone5官网剖析 看苹果公司如何用设计元素

摘要:众所周知,iPhone5已于9月13日发布,其性能、系统、应用以及硬件都被剖析得差不多了,但有多少人注意到了iPhone5网站的设计和实现?实际上Apple每次发布新产品都会用Web实现其特殊性能,本文既是对iPhone5网站上特殊效果的实现分析。

大家都知道iPhone5在9月12号发布了,新产品怎么会少了新网站呢?每次Apple发布新功能总会在网站上做一个Web实现,比如iPhone4的视网膜放大镜、会旋转的电池寿命时钟、new iPad奇怪的滚动效果(ugh)等等。新的iPhone5也一样,网站上同样展示了其新特性,但原理比看起来要更复杂一些:

网页上的iPhone5会在设备解锁后自动播放视频,但奇怪的是:页面上并没有<video>元素,只有<canvas>。即使你使用Chrome检查Web Inspector的“Network”标签,也同样不可能找得到任何视频,但会看到这样奇怪的JPEG图片:

为什么Apple会做如此荒谬的事?它既参与了h.262标准的制定,也开发了Safari,没有理由不知道这样的“捷径”:使用<video>元素。

这是因为,<video>元素在iPhone下必须全屏播放,这就毁了Apple播放内联视频的原意了;而在桌面端,Apple的网站需要兼容所有主流浏览器,但Firefox和Opera不支持h.264(同样,Apple也不可能后退一步使用开源的WebM或者Theora)。

你可以看看这个Retina Macbook Pro“特性”页面——2秒钟的展示视频却需要5M的JPEG图片(并使用了大量独立的HTTP请求)。而iPhone5的网页,Apple使用了一种新方法来避免为每个frame单独请求图片。新的动画仅需要很少的HTTP请求以及1M流量,相比于旧的解决方案性能得到明显提升。

下面是编码后的“视频文件”:

该视频的逻辑实现依赖于ac_flow.js,我建议你在Chrome Web Inspector中打开“Pretty Print”(点击左下角的“{}”)仔细阅读。我不打算在这里做详细的代码解释,所以还是建议你仔细看看代码。

Apple使用的视频压缩方法仅仅会加载frame中更新了的部分:“unlock_001.jpg”和 “unlock_002.jpg”中存储了图片的更新部分,“unlock_manifest.json”文件描述更新部分该如何放置。下面是“unlock_manifest.json”的一个片段:

JPEG文件使用8×8的宏块来编码,所以Apple明智地使用了相同的大小(json里的“blockSize:8”),这还避免了无关的图片误用相同块的问题。(JPEG图片使用4:4:4的色度取样,所以其色度宏块也应该是8×8。)

“imagesRequired”表明,在动画开始时需要加载两张图片——“unlock_001.jpg”和 “unlock_002.jpg”,这两张图片被当作是连续的8×8块流从左向右、自上而下地来处理。(如果我在下面提到JPEG流,指的就是这个。)

这些“frame”看起来就像是base64,但实际上数据也按照base64偏移编码了。换句话说,这里的1Byte实际上是6bit。

下面是Apple解码base64的代码的片段:

每个frame由5字节指令构成,指令的前3字节编码位置来更新<canvas>的相应部分。后2字节则包含需要读取的块数。例如:第一个frame的第一个指令“AAxAC”意味着:从JPEG流中读取2块(“AC”,记住——这是base64编码后的字节),并在<canvas>位置49(“AAx”)进行绘制。

注意:这里并没有从JPEG流中重复利用JPEG块的功能,JPEG块只会在每次请求的时候使用一次,这会引起JPEG潜在的冗余问题,但也保证了manifest 更小,格式也更简单。

除了icons,上图中“最长的”frame就是动画化了的部分,这导致了JPEG流中块复制间的空白。以上就是Apple将视频编码为JPEG图片的原理,但不仅限于视频。

Apple还使用了该压缩方法重新实现了QTVR(虚拟现实)——当你拖动上图中的耳机时,你实际上是在播放耳机转动的视频,这个视频使用的也是相同的JS/JSON/<canvas>压缩技术。

效果怎么样?似乎不怎么样……

出什么问题了?<canvas> API ("drawImage")所花时间甚少,大部分时间都浪费在解码frame以及apply diff上了。

结果证明,在这样的视频中寻找功能特别费时间,因为解码一个单独的视频frame,首先需要解码每个单独的frame——毕竟这个格式的目标只是来解码修改了的部分,这意味着现在我们需要计算没有计算过的位置。

为了缓解这一问题,Apple提供了向前/向后两种视频播放模式(否则,反向旋转耳机会非常慢)。不幸的是,这却直接造成文件大小加倍的问题,但没有解决在用户快速拖拽耳机时“跳帧”的问题。

苹果下一步会怎么做?使用更适合操作二进制文件的东西代替JSON?

似乎Apple正在尝试在新版本中将manifest编码在PNG图片,以此代替当前JSON里的base64字符串。并且因为PNG格式是无损的,而且<canvas>对其支持得非常好,所以很适合编码很多字节的数据,即使它并不是个图片。我对使用PNG格式后对性能性能的影响以及动画文件大小的改变非常感兴趣。

原文链接:iPhone 5 website teardown: How Apple compresses video using JPEG, JSON, and <canvas>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的用Python分析苹果公司股票的代码: ```python import pandas as pd import matplotlib.pyplot as plt import yfinance as yf # 使用yfinance获取苹果公司股票的历史数据 apple_stock = yf.Ticker("AAPL") apple_stock_data = apple_stock.history(period="max") # 计算苹果公司股票的每日收盘价的移动平均线 apple_stock_data['MA50'] = apple_stock_data['Close'].rolling(window=50).mean() apple_stock_data['MA200'] = apple_stock_data['Close'].rolling(window=200).mean() # 绘制苹果公司股票的收盘价和移动平均线的图表 plt.plot(apple_stock_data['Close'], label='AAPL') plt.plot(apple_stock_data['MA50'], label='MA50') plt.plot(apple_stock_data['MA200'], label='MA200') plt.legend(loc='upper left') plt.show() # 计算苹果公司股票的日收益率 apple_stock_data['Daily Return'] = apple_stock_data['Close'].pct_change() # 绘制苹果公司股票的日收益率的直方图 apple_stock_data['Daily Return'].hist(bins=100) plt.show() # 计算苹果公司股票的风险指标 mean_daily_return = apple_stock_data['Daily Return'].mean() std_daily_return = apple_stock_data['Daily Return'].std() print('Mean daily return:', mean_daily_return) print('Standard deviation of daily return:', std_daily_return) ``` 这个代码使用了以下库: - pandas:用于数据分析; - matplotlib:用于绘制图表; - yfinance:用于获取股票数据。 代码中首先使用yfinance库获取了苹果公司股票的历史数据,并计算了每日收盘价的移动平均线。然后使用matplotlib库绘制了收盘价和移动平均线的图表,以及日收益率的直方图。最后计算了苹果公司股票的风险指标,包括平均日收益率和每日收益率的标准差。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值