| 赞 | 87 |
| VIP | |
| 好人卡 | |
| 积分 | 136 |
| 经验 | |
| 最后登录 | 2021-1-24 |
| 在线时间 | 2753 小时 |
- 梦石
- 0
- 星屑
- 13562
- 在线时间
- 2753 小时
- 注册时间
- 2014-10-4
- 回帖
- 705

|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 SixRC 于 2020-9-4 23:48 编辑
更新v1.1
增加了对 disposal method 和 delay time 的支持
现在可以无需额外判断的播放gif 范例及注意见代码
[fold=RM代码]
[pre lang="ruby"]=begin
-----------------------------GIF-Decoder--1-1-------------------------------
-------------------------------------------------SixRC----2020-9-4----------
--------支持透明度等-----不支持那些extension block----能偷的懒我都偷了------
----版本-1-1----------------------------------------------------------------
--增加对-disposal-method-以及-delay-time(秒数)-的支持-----------------------
----传入位图的目标区域会被全部改写(若纯透明则为0000)--请注意和blt的区别-----
---------------------------------范例---------------------------------------
gif = GifDecoder.new "01.gif"
s = Sprite.new
s.bitmap = Bitmap.new(gif.width, gif.height)
while gif.decode(s.bitmap)
(Graphics.frame_rate * gif.delay_time).ceil.times{Graphics.update}
end
(Graphics.frame_rate * gif.delay_time).ceil.times{Graphics.update}
gif.dispose
s.dispose
s.bitmap.dispose
=end
class GifDecoder
READ = Win32API.new("gifdcd", "read_gif", "pp", "l")
DECODE = Win32API.new("gifdcd", "decode_gif", "llllp", "l")
DISPOSE = Win32API.new("gifdcd", "dispose_gif", "l", "v")
attr_reader :width, :height, :delay_time
# 输入文件名 自己读宽高
def initialize(fn)
temp = "\0" * 8
@gif = READ.call(fn, temp)
@width, @height = temp.unpack("ll")
@disposed = false
end
# 如果gif读取完毕 返回false
# 传入位图 待写入的位置 x y 和透明度
# 也就是位图宽高可以大于gif的宽高
# 注意 x + 位图的宽不可以超过 gif 的宽 否则可能溢出
def decode(bitmap, x = 0, y = 0, alpha = 255)
addr = bitmap.addr + bitmap.width * 4 * (bitmap.height - 1)
stride = -bitmap.width * 4
addr = addr + x * 4 + y * stride
dt = "\0" * 4
ret = DECODE.call(@gif, addr, stride, alpha, dt) & 0xFF
@delay_time = dt.unpack("l")[0] / 100.0
return ret != 0
end
# 释放资源
# 每次加载一个gif文件 只能解码一次 没写回头功能
def dispose
return if @disposed
DISPOSE.call(@gif)
@disposed = true
end
end
class Bitmap
CWP = Win32API.new('user32.dll','CallWindowProc','ppiii','i')
GetAddr=[139,116,36,8,139,54,139,118,8,139,118,16,139,124,36,4,137,55,194,16,0].pack("C*")
def addr
s="\0"*4
CWP.call(GetAddr,s,object_id*2+16,0,0)
s.unpack("L")[0]
end
end[/pre]
[/fold]
gifdcd_v11.zip
(234.43 KB, 下载次数: 29, 售价: 1 星屑)
基本完善了 大概不更新了
下面原帖
好久没发帖子了 凑合一下
简言之就是 spec-gif89a 根据这个(加一些别的资料)写了一个 gif 的解码功能(c++) 然后给RGSS接口 然后RGSS端就可以直接播放gif了
虽然其实我是想找现成的然后偷懒的 可是看了好多gif解码库 都感觉有点 ? 不如自己整一个
然后整是整出来了 就是只有基本功能..算了 能用就行 效率也ok 我满足了
(extension block 没处理 disposal method 这个参数也没理)
(别的影响输出的基本上处理了吧)
基本逻辑是搞一个GIF解码类
新建实例传入图片文件名 返回宽高信息
然后每次解码 就是写入到一个位图 解码的返回值true or false false就是文件读完了
读完了释放资源
[pre lang="ruby"]gif = GifDecoder.new "1.gif"
s = Sprite.new
s.bitmap = Bitmap.new(gif.width, gif.height)
while gif.decode(s.bitmap)
5.times{Graphics.update}
# 大部分gif传入上次输出的结果可以正常播放
# 假如传空位图不正常的话
#s.bitmap.clear
end
5.times{Graphics.update}
gif.dispose[/pre]
在每次解码这个过程中
输出的结果可以每帧保存 就能循环放 或者就放一次
每帧暂停的时间就自己掐吧..
具体参数见代码说明
下面正文
这个插到用之前
[fold=RM代码]
[pre lang="ruby"]=begin
-----------------------------GIF-Decoder--1-0-------------------------------
-------------------------------------------------SixRC----2020-9-4----------
--------支持透明度-----不支持很多----能偷的懒我都偷了-----------------------
=end
class GifDecoder
READ = Win32API.new("gifdcd", "read_gif", "pp", "l")
DECODE = Win32API.new("gifdcd", "decode_gif", "llll", "l")
DISPOSE = Win32API.new("gifdcd", "dispose_gif", "l", "v")
attr_reader :width, :height
# 输入文件名 自己读宽高
def initialize(fn)
temp = "\0" * 8
@gif = READ.call(fn, temp)
@width, @height = temp.unpack("ll")
@disposed = false
end
# 如果gif读取完毕 返回false
# 传入位图 待写入的位置 x y 和透明度
# 也就是位图宽高可以大于gif的宽高
# 注意 x + 位图的宽不可以超过 gif 的宽 否则可能溢出
def decode(bitmap, x = 0, y = 0, alpha = 255)
addr = bitmap.addr + bitmap.width * 4 * (bitmap.height - 1)
stride = -bitmap.width * 4
addr = addr + x * 4 + y * stride
ret = DECODE.call(@gif, addr, stride, alpha) & 0xFF
return ret != 0
end
# 释放资源
# 每次加载一个gif文件 只能解码一次 没写回头功能
def dispose
return if @disposed
DISPOSE.call(@gif)
@disposed = true
end
end
class Bitmap
CWP = Win32API.new('user32.dll','CallWindowProc','ppiii','i')
GetAddr=[139,116,36,8,139,54,139,118,8,139,118,16,139,124,36,4,137,55,194,16,0].pack("C*")
def addr
s="\0"*4
CWP.call(GetAddr,s,object_id*2+16,0,0)
s.unpack("L")[0]
end
end[/pre]
[/fold]
然后把
gifdcd.zip
(234.02 KB, 下载次数: 41)
丢到工程目录就行了
至于源码 没啥好看的
就这样吧 |
评分
-
查看全部评分
|