Project1
标题: 【悬赏10V】双线性插值 求优化【更新2.1 @2011-11-28】 [打印本页]
作者: 各种压力的猫君 时间: 2011-11-25 05:35
标题: 【悬赏10V】双线性插值 求优化【更新2.1 @2011-11-28】
本帖最后由 各种压力的猫君 于 2011-11-29 01:32 编辑
悬赏视情况可以随便追加,就这样。
好吧我还在搞双线性插值 lol
这次应该是真正的双线性插值了。
【更新记录】
2011-11-28 2.1
继续优化算法,提高效率(相同情况下对比2.0加快0.2秒),
加权平均的边缘变成了另一种奇怪的样子 = = b 原因不明。
2011-11-25 2.0
大幅优化了算法,提高效率(对比初版(点我)同样是128*128放大3倍,加快1秒)
【测试工程】
双线性插值缩放2.1.zip
(282.07 KB, 下载次数: 36)
【脚本】- #==============================================================================
- # ■ 双线性插值 2.1 by 各种压力的猫君
- #------------------------------------------------------------------------------
- # 双线性插值图像缩放算法
- # 仅供测试,当Bitmap尺寸较大时效率很差暂时不具实用性。
- #------------------------------------------------------------------------------
- # 使用方法:
- # Bilinear.new(bitmap, x_rate, y_rate, type)
- # bitmap :原Bitmap
- # x_rate :横轴放大率
- # y_rate :纵轴放大率
- # type :缩放参数(1:加权平均 2:算术平均)
- #
- # 缩放后的Bitmap会被输出到全局变量$new_bitmap。
- # 缩放结束后可以在全局变量$bilinear_time获取处理全程花费的时间(秒)
- #------------------------------------------------------------------------------
- # 更新记录:
- # 2.1 2011-11-28 优化效率
- # 2.0 2011-11-25 测试版(别问我1.0哪去了)
- #==============================================================================
- class Bilinear
- #--------------------------------------------------------------------------
- # ● 初始化对像
- #--------------------------------------------------------------------------
- def initialize(bitmap, x_rate, y_rate, type = 1)
- # 获取原Bitmap及宽高信息
- @old_bitmap = bitmap
- @old_width = @old_bitmap.width
- @old_height = @old_bitmap.height
- # 生成一个储存所有像素颜色的数组
- @color_array = []
- # 每行从左到右的顺序依次获取颜色并压入数组
- for line in 1..@old_height
- for row in 1..@old_width
- color = @old_bitmap.get_pixel(row, line)
- @color_array.push color
- end
- end
- # 获取放大率
- @x_rate = x_rate
- @y_rate = y_rate
- # 根据放大率计算新Bitmap尺寸
- @new_width = @x_rate * @old_width
- @new_height = @y_rate * @old_height
- # 生成Bitmap
- @new_bitmap = Bitmap.new(@new_width, @new_height)
- # 绘制Bitmap
- draw(type)
- # 返回Bitmap
- $new_bitmap = @new_bitmap.clone
- # 消除临时Bitmap
- @new_bitmap.dispose
- end
- #--------------------------------------------------------------------------
- # ● 绘制Bitmap
- #--------------------------------------------------------------------------
- def draw(type)
- # 记录目前时间,用于统计算法用时
- @time_begin = Time.now
- # 一行一行绘制
- for line in 1..@new_height
- # 过程1:获取本行通用浮点y坐标
- do_math_1(line)
- for row in 1..@new_width
- # 过程2:获取浮点x坐标
- do_math_2(row)
- # 过程3:获取颜色
- do_math_3
- # 过程4:计算颜色
- do_math_4(type)
- # 绘制颜色
- draw_color(row, line)
- end
- end
- # 计算算法用时
- $bilinear_time = Time.now - @time_begin
- end
- #--------------------------------------------------------------------------
- # ● 计算(过程1:获取浮点y坐标及y权)
- #--------------------------------------------------------------------------
- def do_math_1(y)
- # 获取新坐标对应在原图上的浮点坐标
- @y = 100 * y / @y_rate
- # 计算y权
- @ya = @y % 100
- @yb = 100 - @ya
- # 获取底数(floor)
- @yf = @y /= 100
- end
- #--------------------------------------------------------------------------
- # ● 计算(过程2:获取浮点x坐标及x权)
- #--------------------------------------------------------------------------
- def do_math_2(x)
- # 获取新坐标对应在原图上的浮点坐标
- @x = 100 * x / @x_rate
- # 计算x权
- @xa = @x % 100
- @xb = 100 - @xa
- # 获取底数(floor)
- @xf = @x /= 100
- end
- #--------------------------------------------------------------------------
- # ● 计算(过程3:获取颜色)
- #--------------------------------------------------------------------------
- def do_math_3
- # 计算坐标颜色储存在数组中的序列
- index11 = @xf + (@yf - 1) * @old_width - 1
- if @ya == 0
- index21 = index11
- else
- index21 = index11 + @old_width
- end
- if @xa == 0
- index12 = index11
- index22 = index21
- else
- index12 = index11 + 1
- index22 = index21 + 1
- end
- # 从数组中获取颜色
- @color11 = @color_array[index11]
- @color21 = @color_array[index21]
- @color12 = @color_array[index12]
- @color22 = @color_array[index22]
- end
- #--------------------------------------------------------------------------
- # ● 计算(过程4:计算颜色)
- #--------------------------------------------------------------------------
- def do_math_4(type)
- # 分解颜色
- @c11 = decompose_color(@color11)
- @c21 = decompose_color(@color21)
- @c12 = decompose_color(@color12)
- @c22 = decompose_color(@color22)
- if type == 1
- # 加权
- @c11 = weighted_average(@c11, @xa)
- @c21 = weighted_average(@c21, @xa)
- @c12 = weighted_average(@c12, @xb)
- @c22 = weighted_average(@c22, @xb)
- # 计算新颜色
- @r = ((@c11[0] + @c12[0]) * @ya + (@c21[0] + @c22[0]) * @yb) / 10000
- @g = ((@c11[1] + @c12[1]) * @ya + (@c21[1] + @c22[1]) * @yb) / 10000
- @b = ((@c11[2] + @c12[2]) * @ya + (@c21[2] + @c22[2]) * @yb) / 10000
- @a = ((@c11[3] + @c12[3]) * @ya + (@c21[3] + @c22[3]) * @yb) / 10000
- elsif type == 2
- # 计算新颜色
- @r = (@c11[0] + @c12[0] + @c21[0] + @c22[0]) / 4
- @g = (@c11[1] + @c12[1] + @c21[1] + @c22[1]) / 4
- @b = (@c11[2] + @c12[2] + @c21[2] + @c22[2]) / 4
- @a = (@c11[3] + @c12[3] + @c21[3] + @c22[3]) / 4
- end
- end
- #--------------------------------------------------------------------------
- # ○ 分解颜色
- #--------------------------------------------------------------------------
- def decompose_color(color)
- r = color.red
- g = color.green
- b = color.blue
- a = color.alpha
- color_array = [r, g, b, a]
- return color_array
- end
- #--------------------------------------------------------------------------
- # ○ 加权运算
- #--------------------------------------------------------------------------
- def weighted_average(array, d)
- new_array = []
- array.each do |i|
- new_array.push i * d
- end
- return new_array
- end
- #--------------------------------------------------------------------------
- # ● 绘制颜色
- #--------------------------------------------------------------------------
- def draw_color(x, y)
- color = Color.new(@r, @g, @b, @a)
- @new_bitmap.set_pixel(x, y, color)
- end
- end
复制代码 为什么不让我换行!!!
【历史版本】(以下链接均链接到我的6R空间日志)
2.0版 大幅优化效率
1.0版(某个脑残算法版本,刚发布就删除了,尸首已经找不到了)
初版 最初的思路
【悬赏解决以下问题】
①效率再提高
②采用加权平均时图像边缘的锯齿
③调用方法能否改成类似@new_bitmap = Bilinear.new(@bitmap, 3, 3, 2) 这样
多多益善,就算效果不是非常好也有经验奖励,
VIP悬赏无上限追加{:nm_4:}(当然不能超过我财力范围 {:nm_7:} )