当前位置:首页 > 图片 > 时尚娱乐 > 正文
文章正文

ios 播放gif动态图片不显示 GIF 图片最佳实践 - FLAnimatedImage

图片 > 时尚娱乐 > :ios 播放gif动态图片不显示 GIF 图片最佳实践 - FLAnimatedImage是由美文导刊网(www.eorder.net.cn)为您精心收集,如果觉得好,请把这篇文章复制到您的博客或告诉您的朋友,以下是ios 播放gif动态图片不显示 GIF 图片最佳实践 - FLAnimatedImage的正文:

GIF 图片最佳实践 - FLAnimatedImage

FLAnimatedImage 简介

FLAnimatedImage 是 Flipboard 团队开发的在它们 App 中渲染 GIF 图片使用的库。 后来 Flipboard 将 FLAnimatedImage 开源出来供大家使用。 所以你不用担心它在实践中会不会出现问题, 毕竟已经在 Flipboard 这种 App 上面经过充分的实践验证了。

因为 Flipboard App 中很多频道会展示大量的 GIF 图片,而 iOS 原生的系统库中并没有提供对 GIF 很好的支持,所以 FLAnimatedImage 就应运而生了。

基本思路

大家如果在 iOS 中处理过 GIF 图片, 如果通过原生系统提供的能力, 可能只有两种方式。 并且这两种方式都不是专门针对于 GIF 的解决方案,更像是一种 hack。

第一种方式, UIImage 虽然提供了一种创建连续切换的动画图片的能力, 但这个能力更像是为了那些简单动画而服务的。 比如加载数据时候显示的 loading 图片。 如果将 GIF 图片通过这种能力来显示,会带来诸多问题。

第二种方式,可能是大家用的最多的了。 就是创建一个 UIWebView 然后在这里面把 GIF 显示出来。 但从原理上来想, UIWebView 并不是为了显示 GIF 图片而生的。 其实也算不上最佳实践。

但 iOS 原生系统库目前只提供了这几个能力, 用这些 hack 方式也是无奈之举。 关于这些问题, Flipboard 官方的技术 blog 上面有详细的说明, 感兴趣的同学可以参考这里:

使用 FLAnimatedImage

给大家介绍了基本的问题背景, 咱们就来看看 FLAnimatedImage 是如何解决这个问题的吧。 我们可以通过 将 FLAnimatedImage 集成进来, 创建这样一个 Cartfile :

github"Flipboard/FLAnimatedImage"

然后执行:

carthageupdate

就可以将 FLAnimatedImage 拉取下来。 当然, 你也可以使用 Cocoapods, 如何集成请参考 FLAnimatedImage 的 Github 主页:

如果你使用的 Swift 可以在 Bridgeing Header 中引入 FLAnimatedImage:

#import <FLAnimatedImage/FLAnimatedImage.h>

随后在需要的地方这样调用 FLAnimatedImage 就可以了:

//创建 FLAnimatedImageView

letimageView = FLAnimatedImageView(frame: CGRect(x: 0, y: 0, width: 400, height: 400))

self.view.addSubview(imageView)

letimageURLString = "https://media.giphy.com/media/Nm8ZPAGOwZUQM/giphy.gif"

ifletimageURL = URL(string: imageURLString) {

//读取图片

letsession = URLSession(configuration: URLSessionConfiguration.default)

session.dataTask(with: imageURL, completionHandler: { (data, response, error) in

ifdata != nil{

letimage = FLAnimatedImage(animatedGIFData: data)

imageView.animatedImage = image

}

}).resume()

}

这里给大家简单讲解一下, 首先我们初始化一个 FLAnimatedImageView 实例。 然后 URLSession 读取图片数据, 得到图片的数据 data 后, 用这个数据初始化 FLAnimatedImage 实例, 最后将它设置给 animatedImage 属性。 这样就完成了, 其余的 GIF 渲染工作都由 FLAnimatedImage 来处理。

上面的代码应该比较简明易懂,如果有疑问可以在留言中提出~

GIF 渲染原理

为什么说 FLAnimatedImage 相对于 iOS 原生的几种 hack 方式更趋近于最佳实践呢? 咱们简单聊聊 FLAnimatedImage 渲染 GIF 图片的原理。FLAnimatedImage 会有两个线程同时在运转。 其中一个线程负责渲染 GIF 的每一帧的图片内容(所谓的渲染,大体上就是加载 GIF 文件数据,然后抽取出来当前需要哪一帧)。这个加载图片的过程是在异步线程进行的。

然后 FLAnimatedImage 会有一个内存区域专门放置这些渲染好的帧。 这时候,在主线程中的 ImageView 会根据当前需要,从这个内存区域中读取相应的帧。这是一个典型的生产者-消费者问题。

这样最大限度的保证主线程不去处理图片渲染的操作,并且我们刚才说的那个内存区域, 也是经过一系列的动态管理,以提升性能。 并且 FLAnimatedImage的渲染线程,在数据没有准备好的时候,不会加锁等待,而是直接返回 nil。 这样也能避免一些实现中为了图片序列完全显示正确,而造成性能卡顿的问题。

这里给大家做了一个简要的介绍,关于 FLAnimatedImage 更详细的内容, 大家可以参考 Flipboard 的官方文档:

结语

FLAnimatedImage 提供了一种更好的 GIF 图片渲染实践。 下次如果你的项目中需要使用 GIF 图片的时候,就可以考虑使用 FLAnimatedImage 来操作, 而不是用 UIWebView 费时费力的 hack 了。 大家如果有一些建议,或是更好的实践,也非常欢迎在留言中一起讨论。

如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~返回搜狐,查看更多

Swift 玩转gif

(点击上方公众号,可快速关注)

来源:大石头布

链接:http://www.jianshu.com/p/b60a06bdb375

gif study

众所周知,iOS默认是不支持gif类型图片的显示的,但是我们项目中常常是需要显示gif为动态图片。那肿么办?第三方库?是的 ,很多第三方都支持gif , 如果一直只停留在用第三方上,技术难有提高。上版本的 Kingfisher 也支持gif ,研究了一番,也在网上搜索了一番,稍微了解了下iOS实现gif的显示,在此略做记录。

本篇文章要实现的效果如图:

gif显示效果

可以开始和暂停gif的播放,滑动时停止播放,这个简书也是这么做得,好多app为了滑动时顺畅,停止了gif。

下面要进入正文啦!

期待…

分解gif帧进行显示

我们一般从网络上下载的gif图片其实是将很多帧静态图片循环播放产生的动态效果,那么在iOS中,如果我们想要显示动态图,同样需要先把gif资源解析为一阵一阵的UIImage然后设定间隔时长,不断播放即可。思路是不是很简单呢?那么看看如何实现。

分几个步骤:

  1. 将gif图片转为NSData。

  2. 根据NSData获取CGImageSource对象

  3. 获取帧数

  4. 根据帧数获取每一帧对应的UIImage对象和时间间隔

  5. 循环播放

首先我们需要引入import ImageIO , 提供了很多对图片操作的函数。

这里我们从网上down了一个gif的图片,其实下载也是一样的 ,我们需要的是NSData类型的数据,用NSURLSession下载也可以得到NSData类型的数据,这里下载的数据如何判断是否为gif呢?

Kingfisher 库中给出了解决方案,每种格式的图片前面几位都是固定的。所以只需要对比就能判断出类型,这里给出Kingfisher判断类型的代码。

privatelet pngHeader: [UInt8]= [0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A]

privatelet jpgHeaderSOI: [UInt8]= [0xFF,0xD8]

privatelet jpgHeaderIF: [UInt8]= [0xFF]

privatelet gifHeader: [UInt8]= [0x47,0x49,0x46]

enumImageFormat{

caseUnknown,PNG,JPEG,GIF

}

extensionNSData{

varkf_imageFormat: ImageFormat{

varbuffer= [UInt8](count: 8,repeatedValue: 0)

self.getBytes(&buffer,length: 8)

ifbuffer== pngHeader{

return.PNG

}elseifbuffer[0]== jpgHeaderSOI[0]&&

buffer[1]== jpgHeaderSOI[1]&&

buffer[2]== jpgHeaderIF[0]

{

return.JPEG

}elseifbuffer[0]== gifHeader[0]&&

buffer[1]== gifHeader[1]&&

buffer[2]== gifHeader[2]

{

return.GIF

}

return.Unknown

}

}

有了这个扩展判断起来就方便很多了。

为了使demo简单,我们直接将gif放在本地沙盒。下载好直接拖进项目就OK了。

这样就可以很容易的得到NSData类型的数据

let path= NSBundle.mainBundle().pathForResource("xxx",ofType: "gif")

let data= NSData(contentsOfFile: path!)

第一步已经完成啦。

然后通过CGImageSourceCreateWithData 方法创建一个CGImageSource 对象 。

// kCGImageSourceShouldCache : 表示是否在存储的时候就解码

// kCGImageSourceTypeIdentifierHint : 指明source type

let options: NSDictionary= [kCGImageSourceShouldCache asString: NSNumber(bool: true),kCGImageSourceTypeIdentifierHint asString: kUTTypeGIF]

guard let imageSource= CGImageSourceCreateWithData(data,options)else{

return

}

这里的options是为了显示优化。提前解码,指定类型。

拿到CGImageSource 对象就可以为所欲为了。

// 获取gif帧数

let frameCount= CGImageSourceGetCount(imageSource)

var images= [UIImage]()

var gifDuration= 0.0

foriin0..< frameCount{

// 获取对应帧的 CGImage

guard let imageRef= CGImageSourceCreateImageAtIndex(imageSource,i,options)else{

return

}

ifframeCount== 1{

// 单帧

gifDuration= Double.infinity

}else{

// gif 动画

// 获取到 gif每帧时间间隔

guard let properties= CGImageSourceCopyPropertiesAtIndex(imageSource,i,nil),gifInfo= (properties as NSDictionary)[kCGImagePropertyGIFDictionary as String]as?NSDictionary,

frameDuration= (gifInfo[kCGImagePropertyGIFDelayTime as String]as?NSNumber)else

{

return

}

// print(frameDuration)

gifDuration+= frameDuration.doubleValue

// 获取帧的img

let image= UIImage(CGImage: imageRef,scale: UIScreen.mainScreen().scale,orientation: UIImageOrientation.Up)

// 添加到数组

images.append(image)

}

}

先获取帧数,然后循环根据帧数获取对应的图片,然后获取没帧间隔时间。累加时间间隔得到总共的时间,把图片存在一个图片数组中。

有了这些参数,我们就可以播放gif了。

界面上随便拖出来一个 UIImageView 然后给以下属性赋值即可。

imgV.contentMode= .ScaleAspectFit

imgV.animationImages= images

imgV.animationDuration= gifDuration

imgV.animationRepeatCount= 0// 无限循环

imgV.startAnimating()

运行项目,发现gif动起来了。

happy…

原来gif也没那么难,哈哈… …

但是这样你添加一个开始和暂停的按钮

@IBAction func start(sender: AnyObject){

if!imgV.isAnimating(){

imgV.startAnimating()

}

}

@IBAction func stop(sender: AnyObject){

ifimgV.isAnimating(){

imgV.stopAnimating()

}

}

你会发现,暂停时白板,什么图都没有,而且滚动的时候也不会暂停。。。

吐血…

这只是个开始,后面的路还很长,坐好继续。

处理gif的暂停、播放 滑动暂停等

以下部分基本上算是对Kingfisher 的一个理解,我们继续。

简单说下思路,要实现暂停在某帧,滑动暂停某帧这个就不能用UIImageView的startAnimating直接操作了,需要我们自己处理帧和动画,动画在Kingfisher中使用CADisplayLink处理的,写了一个UIImageView的子类AnimatedImageView,重写了startAnimating 、 stopAnimating 等方法。关于CADisplayLink不熟悉的,看这篇文章 – CADisplayLink , 需要滑动暂停就把 CADisplayLink 加到 NSDefaultRunLoopMode模式的runloop下。 关于对帧的处理单独写了一个Animator . 下面来看看具体实现。

Animator 类处理帧

首先定义一个结构体,里面就有两个属性UIImage 图像 和 NSTimeInterval 帧之间时间间隔。

structAnimatedFrame{

varimage: UIImage?

let duration: NSTimeInterval

staticfunc null()-> AnimatedFrame{

returnAnimatedFrame(image: .None,duration: 0.0)

}

}

接着就可以创建一个 Animator 并定义一些需要用的属性

classAnimator{

privatelet maxFrameCount: Int= 100// 最大帧数

privatevarimageSource:CGImageSource! // imageSource 处理帧相关操作

privatevaranimatedFrames= [AnimatedFrame]()//

privatevarframeCount= 0// 帧的数量

privatevarcurrentFrameIndex= 0// 当前帧下标

privatevarcurrentPreloadIndex= 0// 当前预缓存帧的下标

privatevartimeSinceLastFrameChange: NSTimeInterval= 0.0// 距离上一帧改变的时间

/// 循环次数

privatevarloopCount= 0

/// 做大间隔

privatelet maxTimeStep: NSTimeInterval= 1.0

}

然后是一个队数据操作的方法,因为Kingfiher是处理网络图片的,所以我这边处理方式略不同

/**

根据data创建 CGImageSource

- parameter data: gif data

*/

func createImageSource(data:NSData){

let options: NSDictionary= [kCGImageSourceShouldCache asString: NSNumber(bool: true),kCGImageSourceTypeIdentifierHint asString: kUTTypeGIF]

imageSource= CGImageSourceCreateWithData(data,options)

}

这个方法就是前面的根据NSData 获取 CGImageSource 对象,以备后用。

然后写一个将每一帧转换为我们刚定义的结构体 AnimatedFrame 对象

/// 准备某帧 的 frame

func prepareFrame(index: Int)-> AnimatedFrame{

// 获取对应帧的 CGImage

guard let imageRef= CGImageSourceCreateImageAtIndex(imageSource,index,nil)else{

returnAnimatedFrame.null()

}

// 获取到 gif每帧时间间隔

guard let properties= CGImageSourceCopyPropertiesAtIndex(imageSource,index,nil),gifInfo= (properties asNSDictionary)[kCGImagePropertyGIFDictionary asString]as?NSDictionary,

frameDuration= (gifInfo[kCGImagePropertyGIFDelayTime asString]as?NSNumber)else

{

returnAnimatedFrame.null()

}

let image= UIImage(CGImage: imageRef,scale: UIScreen.mainScreen().scale,orientation: UIImageOrientation.Up)

returnAnimatedFrame(image: image,duration: Double(frameDuration)??0.0)

}

就是根据imageSource获取CGImage再转为UIImage , 然后获取帧间隔时间,构建结构体。 很easy 。没啥说的。

下面还需要一个预备所有帧的方法

/**

预备所有frames

*/

func prepareFrames(){

frameCount= CGImageSourceGetCount(imageSource)

iflet properties= CGImageSourceCopyProperties(imageSource,nil),

gifInfo= (properties asNSDictionary)[kCGImagePropertyGIFDictionary asString]as?NSDictionary,

loopCount= gifInfo[kCGImagePropertyGIFLoopCountasString]as?Int{

self.loopCount= loopCount

}

// 总共帧数

let frameToProcess= min(frameCount,maxFrameCount)

animatedFrames.reserveCapacity(frameToProcess)

// 相当于累加

animatedFrames= (0..

这里其实就是得到总帧数然后给animatedFrames赋值,Kingfisher这里使用了readuce,累加的方式pure 方法是将一个值转成一个单值数组。

privatefunc pure(value: T)-> [T]{

return[value]

}

根据下表取帧

/**

根据下标获取帧

*/

func frameAtIndex(index: Int)-> UIImage?{

returnanimatedFrames[index].image

}

当前帧和contentMode属性

varcurrentFrame: UIImage?{

returnframeAtIndex(currentFrameIndex)

}

varcontentMode: UIViewContentMode= .ScaleToFill

AnimatedImageView-可以播放gif的ImageView

基本成型,还差一个更新当前帧的方法,暂时不处理,先看去用实现一个继承自UIImageView的AnimatedImageView 并声明几个属性。

publicclassAnimatedImageView: UIImageView{(ios 播放gif动态图片不显示)

/// 是否自动播放

publicvarautoPlayAnimatedImage= true

/// `Animator` 对象 将帧和指定图片存储内存中

privatevaranimator: Animator?

/// displayLink 为懒加载 避免还没有加载好的时候使用了 造成异常

privatevardisplayLinkInitialized: Bool= false

}

这里利用 CADisplayLink 不断执行某个方法,等达到帧之间的间隔时间的时候就去更新UIImageView的 layer 的 contens 属性。这个属性需要一个CGImage的对象。

为了防止AnimatedImageView 和 CADisplayLink 之间的循环引用,Kingfisher在AnimatedImageView 内部写了一个代理类。

/// 防止循环引用

classTargetProxy{

privateweak vartarget: AnimatedImageView?

init(target: AnimatedImageView){

self.target= target

}

@objc func onScreenUpdate(){

target?.updateFrame()

}

}

就是通过TargetProxy 来调用 AnimatedImageView 中的 updateFrame 方法,大家可以先写一个空方法。

然后创建一个CADisplayLink对象,这里使用懒加载。

privatelazy vardisplayLink: CADisplayLink= {

self.displayLinkInitialized= true

let displayLink= CADisplayLink(target: TargetProxy(target: self),selector: #selector(TargetProxy.onScreenUpdate))

displayLink.addToRunLoop(NSRunLoop.mainRunLoop(),forMode: self.runLoopMode)

displayLink.paused= true

returndisplayLink

}()

用这个self.displayLinkInitialized 标志 CADisplayLink 已经加载,然后用代理就调用自己的 updateFrame()方法

在添加个指定RunLoopMode的属性

// NSRunLoopCommonModes

publicvarrunLoopMode= NSDefaultRunLoopMode{

willSet{

ifrunLoopMode== newValue{

return

}else{

stopAnimating()

displayLink.removeFromRunLoop(NSRunLoop.mainRunLoop(),forMode: runLoopMode)

displayLink.addToRunLoop(NSRunLoop.mainRunLoop(),forMode: newValue)

startAnimating()

}

}

}

Kingfisher 默认是NSRunLoopCommonModes 滑动不暂停,我这边换成NSDefaultRunLoopMode 滑动暂停 。

NSRunLoopCommonModes 包含两个模式 UITrackingRunLoopMode 和 NSDefaultRunLoopMode , 其中UITrackingRunLoopMode 是滑动时候的模式

,如果只在 NSDefaultRunLoopMode 模式下,那滑动模式就不会执行CADisplayLink 的方法, NSTimer 也可以指定 模式。非本篇重点 ,这里就不细说了

kingfisher 是重写了 image 属性进行Animator的初始化和重置的 , 这里为了demo的easy 我们给 AnimatedImageView 新增一个属性,叫 gifData.

publicvargifData:NSData?{

didSet{

iflet gifData= gifData{

animator= nil

animator= Animator()

animator?.createImageSource(gifData)

animator?.prepareFrames()

didMove()

setNeedsDisplay()

layer.setNeedsDisplay()

}

}

}

创建Animator对象 ,缓存帧。 这里didMove() 方法是处理自动播放的

privatefunc didMove(){

ifautoPlayAnimatedImage&& animator!= nil{

iflet_= superview,_= window{

startAnimating()

}else{

stopAnimating()

}

}

}

后面会重写startAnimating 和 stopAnimating .

先来看 CADisplayLink 每次调用的方法updateFrame() , 这里默认是每秒60次 , 根据屏幕刷新频率。

要实现updateFrame() 放法首先要在,Animator 中添加一个更新当前帧的方法。上面提到的,现在可以来写了。

func updateCurrentFrame(duration: CFTimeInterval)-> Bool{

// 计算距离上一帧 改变的时间 每次进来都累加 直到frameDuration <= timeSinceLastFrameChange 时候才继续走下去

timeSinceLastFrameChange+= min(maxTimeStep,duration)

guard let frameDuration= animatedFrames[safe: currentFrameIndex]?.duration where frameDuration<= timeSinceLastFrameChange else{

returnfalse

}

// 减掉 我们每帧间隔时间

timeSinceLastFrameChange-= frameDuration

let lastFrameIndex= currentFrameIndex

currentFrameIndex+= 1// 一直累加

// 这里取了余数

currentFrameIndex= currentFrameIndex% animatedFrames.count

ifanimatedFrames.count< frameCount{

animatedFrames[lastFrameIndex]= prepareFrame(currentPreloadIndex)

currentPreloadIndex+= 1

currentPreloadIndex= currentPreloadIndex% frameCount

}

returntrue

}

传入的duration 是 displayLink.duration 默认是 1/60 秒,这里先对每次的duration进行累加,直到我们的帧间隔时间小于等于它了 才去获取当前帧和增加下标,返回true , 否则一直返回false

然后AnimatedImageView中的 updateFrame 方法就是调用那个方法,直到它返回true才进行处理,这里就是调用了layer.setNeedsDisplay()

privatefunc updateFrame(){(ios 播放gif动态图片不显示)

ifanimator?.updateCurrentFrame(displayLink.duration)??false{

// 此方法会触发 displayLayer

layer.setNeedsDisplay()

}

}

layer.setNeedsDisplay() 会触发 displayLayer 方法,我们只要重写这个方法,就能处理每帧的显示了。

override publicfunc displayLayer(layer: CALayer){

iflet currentFrame= animator?.currentFrame{

layer.contents= currentFrame.CGImage

}else{

layer.contents= image?.CGImage

}

}

搞了这么多,终于到显示了,不容易呀。。。

这里重写了几个方法,都去调用了didMove

override publicfunc didMoveToWindow(){

super.didMoveToWindow()

didMove()

}

override publicfunc didMoveToSuperview(){

super.didMoveToSuperview()

didMove()

}

这里gif的暂停是利用了CADisplayLink的paused属性控制的

override publicfunc isAnimating()-> Bool{

ifdisplayLinkInitialized{

return!displayLink.paused

}else{

returnsuper.isAnimating()

}

}

/// Starts the animation.

override publicfunc startAnimating(){

ifself.isAnimating(){

return

}else{

displayLink.paused= false

}

}

/// Stops the animation.

override publicfunc stopAnimating(){

super.stopAnimating()

ifdisplayLinkInitialized{

displayLink.paused= true

}

}

这里displayLinkInitialized 判断CADisplayLink是否加载好了。

最后记得在对象销毁的时候吧displaylink也停掉

deinit{

ifdisplayLinkInitialized{

displayLink.invalidate()

}

}

至此,所有基本功能已经全部OK了,使用也很简单。

let path= NSBundle.mainBundle().pathForResource("xxx",ofType: "gif")

let data= NSData(contentsOfFile: path!)

imgV.gifData= data

默认是自动播放,可以手动设置。

文章比较长,可能描述的不是很到位,有啥不清楚可以留言交流。

github地址:https://github.com/smalldu/ImageDemo

关注「 iOS大全 」

看更多精选 iOS 技术文章

↓↓↓返回搜狐,查看更多


一.苹果手机相册怎么不能显示gif动态图

苹果由于ios系统原因,是不支持查看gif动态图像的,你可以用以下两个方法来查看:
iPhone看gif方法一:使用美图GIF来查看GIF动画:
1筏互摧就诋脚搓协掸茅.下载美图GIF。
2.安装方式与其他软件是相同的,如果你的iphone越狱并安装了91助手等软件。
3. 安装好后,用美图GIF来打开gif动画图片,就可以看到你最初看到的效果了。
iPhone看gif方法二:iPhone不安装软件查看gif动画的方法
1.点击桌面上的“照片”图标,选择并打开那张带有动画效果的gif图片,然后点击左下角的“菜单”图标。
3.开启邮件的草稿箱,打开草稿文件,图片的动态效果就会展示出来了。


二.苹果手机相册怎么不能显示GIF动态图?

苹果由于ios系统原因,是不支持查看gif动态图像的,你可以用以下两个方法来查看:
iPhone看gif方法一:使用美图GIF来查看GIF动画:
1.下载美图GIF。
2.安装方式与其他软件是相同的,如果你的iphone越狱并安装了91助手等软件。
3. 安装好后,用美图GIF来打开gif动画图片,就可碃矗百匪知睹版色保姬以看到你最初看到的效果了。
iPhone看gif方法二:iPhone不安装软件查看gif动画的方法
1.点击桌面上的“照片”图标,选择并打开那张带有动画效果的gif图片,然后点击左下角的“菜单”图标。
3.开启邮件的草稿箱,打开草稿文件,图片的动态效果就会展示出来了。

其他答案

现在可以直接通过下载一个简单的APP来搞定了,免费的有 “动态图相册”软碃矗百匪知睹版色保姬件,可以下载及保存微博里的gif,不得姐等App中的gif,更重要的是,还可以了随时分享你保存的gif到QQ啊,微博啊。希望能帮到你哈
ljingge5833 2015-9-2

查看"电子数码"分类更多问题

回顶部↑

三.ios启动播放gif为什么跳不到主页面

1. 使用UIWebView播放
// 设定位置和大小
CGRect frame = CGRectMake(50,50,0,0);
frame.size = [UIImage imageNamed:@"guzhang.gif"].size;
// 读取gif图片数据
NSData *gif = [NSData da姬福灌凰弑好鬼瞳邯困taWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"guzhang" ofType:@"gif"]];
// view生成
UIWebView *webView = [[UIWebView alloc] initWithFrame:frame];
webView.userInteractionEnabled = NO;//用户不可交互
[webView loadData:gif MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
[self.view addSubview:webView];
[webView release];

2.将gif图片分解成多张png图片,使用UIImageView播放。
代码如下:
UIImageView *gifImageView = [[UIImageView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
NSArray *gifArray = [NSArray arrayWithObjects:[UIImage imageNamed:@"1"],
[UIImage imageNamed:@"2"],
[UIImage imageNamed:@"3"],
[UIImage imageNamed:@"4"],
[UIImage imageNamed:@"5"],
[UIImage imageNamed:@"6"],
[UIImage imageNamed:@"7"],
[UIImage imageNamed:@"8"],
......余下全文>>

查看"互联网"分类更多问题

回顶部↑

四.iOS 怎么显示gif动态图啊,求各位指点一二

iOS只是系统相册不支持gif,Safari、iMessage、备忘录等等场景都是氦稜份谷莓咐逢栓抚兢支持的。绝大部分的第三方app也都是支持的。



五.IPHONE如何看GIF格式的图片

谁说不支持GIF,当然可以看,装个mobile finder(装上后的图标显示为mobilestudio)袱郸递肝郛菲店十锭姜,基本上可以看许多格式文件,比如doc、pdf,更别说jpg gif了,里边可自建文件夹,存放自己喜欢的图片、文章、甚至音频视频


六.如何在iPhone/iPad里查看GIF图片的动态效果

[提要]这些GIF图片一旦保存到iPhone/iPa尝掸佰赶脂非拌石饱将d的相册里,如果没有支持播放GIF图片的应用程序,就不能再次欣赏那些有趣的动画。其实只需要简单三个步骤,就可以让你在原生应用【照片】中看到动画效果 


七.ipad为什么不能看gif动图

动图一般为GIF格式,ios系统不支持gif格式,无法播放和保持。
简介:GIF就是图像交换格式(Graphics Interchange Format),它有以下几个特点:
1)GIF只支持256色以内的图像;
2)GIF采用无损压缩存储,在不影响图像质量的情况下,可以生成很小的文件;
3)它支持透明色,可以使图像浮现在背景之上;
4)GIF文件可以制作动画,这是它最突出的一个特点。
GIF文件的众多特点恰恰适应了Internet的需要,于是它成了Internet上最流行的图像格式,它的出现为Internet注入了一股新鲜的活力。GIF酣处丰肺莶镀奉僧斧吉文件的制作也与其它文件不太相同。


八.ios8为什么webview显示不了gif图了

在适当的地方加入下面的代码:

NSString* gifFileName = @"文件名.gif";
NSMutableString* htmlStr = [NSMutableString string];
[htmlStr appendString:@"Hello Honey"];
[htmlStr appendString:@"<p><img src=\""];
[htmlStr appendFormat:@"%@",gifFileName];
[htmlStr appendString:@"\" alt=\"picture&#讥功罐嘉忒黄闺萎酣联92;"/>"];
[WebView loadHTMLString:htmlStr baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];

别忘了添加资源文件 “文件名.gif”


九.ios系统为什么把gif保存到相册不动了?

.gif文件没有变化,还是原来的会动的;只是相册读取的时候,只读取动态gif的第一帧画面,所以显示的时迹辅管恍攮喝归桶害垃候就“不动”了呀~~

  • gif动态图片倒着放 用Python将GIF倒放
  • gif动态图片女生看的 美女搞笑gif动态图:大妹子啊我只是个送快递的
  • gif动态图片是网页显示 GIF表情包今天30岁!你知道它是如何火起来的吗?
  • gif动态图片欢迎
  • gif动态图片加速 GIF搞笑动态图片
  • gif 动态 图片
  • gif动态图片 画面太小 搞笑人物gif动态图片_生活中的尴尬场面
  • gif动态图片不会动
  • gif动态图片打飞机 爆笑Gif动图汇 第050弹!直播打飞机…
  • gif动态图片图片 GIF动态图制作大全
  • gif动态图片怎么发送 如何在iPhone上保存Gif图?
  • gif动态图片连续 GIF搞笑动态图片
  • giF祝福动态图片
  • ooxxgif动态图片欧美 搞笑gif:好带感,超冷艳
  • gif怕怕动态图片 爆笑动态图:啪啪啪,美女表情又来了(第801期)
  • gif动态图片网站 你要的GIF动态图在这里了,都拿走吧!
  • gif动态图片文艺 GIF 动图发展史上的 11 个重要时刻
  • gif动态图片基地 几万张GIF动态图片,来领了。
  • gif动态图片 修改 修改gif图片尺寸大小的方法
  • java gif 动态图片 GIF表情包今天30岁!你知道它是如何火起来的吗?
  • ios 播放gif动态图片不显示 GIF 图片最佳实践 - FLAnimatedImage由美文导刊网(www.eorder.net.cn)收集整理,转载请注明出处!原文地址http://www.eorder.net.cn/pic51877/

    文章评论
    Copyright © 2006 - 2016 www.eorder.net.cn All Rights Reserved
    美文导刊网 版权所有