查看: 1984|回复: 0

[原创发布] Bitmap#blt/#move/#changehue#remove_black

[复制链接]
梦石
0
星屑
6483
在线时间
119 小时
注册时间
2020-1-8
回帖
205
发表于 2022-7-3 22:00:21 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 RPGzh500223 于 2022-8-7 17:35 编辑

[pre lang="ruby"]class Bitmap
  dll = "bitmap0.dll"

  Blt = Win32API.new(dll, 'blt', 'LLLLLL', 'L')
  Bit_Move = Win32API.new(dll, 'bit_move', 'LLLLL', 'L')
  ChangeHue = Win32API.new(dll, 'changehue', 'LL', 'L')
  ChangehueTo = Win32API.new(dll, 'changehueTo', 'LLL', 'L')
  RemoveB = Win32API.new(dll, 'remove_black_F', 'L', 'L')
  RemoveW = Win32API.new(dll, 'remove_white_F', 'L', 'L')
  
  def to_int
    self.__id__
  end
  
  # 仿Btimap#blt,误差很小,只快了一点点……
  # 建议实际混合区域超过 64*64 大小时使用,超过200行,开了2个线程执行
  # src_bitmap_rect 为 nil 时 即src_bitmap.rect
  def blt0(dx, dy, src_bitmap, src_bitmap_rect = nil, alpha = 255)
    Blt.call(self, dx, dy, src_bitmap, src_bitmap_rect.__id__, alpha)
  end
  
  # 直接复制源位图区域至目标位图的指定位置,特殊的blt
  # src_bitmap_rect 为 nil 时 即src_bitmap.rect
  def move0(dx, dy, src_bitmap, src_bitmap_rect = nil)
    Bit_Move.call(self, dx, dy, src_bitmap, src_bitmap_rect.__id__)
  end
  
  # 参照网上 rgb_to_hsv / hsv_to_rgb 的方法,SSE实现
  # 仿Bitmap#hue_change,前3次误差很小,不适于连续改变色相
  # 建议位图大小超过 10*10 时使用,640*480的理想的大小(w * h => 4 * n)时接近Bitmap#hue_change的5倍
  # hue -360..360
  def changehue!(hue)
    ChangeHue.call(self, hue)
  end
  
  # 适用于连续改变色相的情况(hue参数动态变化)
  # 在前面的方法中无法修复连续改变色相带来的问题,笨办法额外内存备份源数据
  # 源位图(src_bitmap)与目标位图(self)大小需一致
  def changehueTo(src_bitmap, hue)
    ChangeHueTo.call(self, src_bitmap, hue)
  end
  
  # 仿photoshop R、G、B通道滤色去除黑色(0,0,0)背景,与ps结果误差很小
  # 有时精灵加法呈现的效果“失真”,可以考虑试试这个
  def remove_black!
    RemoveB.call(self)
  end
  
  # 白色为(255, 255, 255)
  def remove_white!
    RemoveW.call(self)
  end
end[/pre]

增加remove_black!方法(640 * 480大小,我的电脑310+次/秒),其余未变

remove_black!的计算说明及演示
[pre lang="ruby"]vpt = Viewport.new(0, 0, 640, 480)
vpt.color.set(0, 255, 0)

bitmap = Bitmap.new("23.png") # 黑色背景图片
sprite = Sprite.new
sprite.bitmap = bitmap

sprite.ox, sprite.oy = bitmap.width / 2, bitmap.height / 2
sprite.x, sprite.y = 320, 240

#sprite.blend_type = 1


bitmap.width.times do |x|
  Graphics.update
  bitmap.height.times do |y|
    color = bitmap.get_pixel(x, y)
    r, g, b = color.red, color.green, color.blue
   
    a = r + g - r * g / 255
    a = a + b - a * b / 255
   
    color.alpha = a
   
    if a != 0
      color.red = r * 255 / a
      color.green = g * 255 / a
      color.blue = b * 255 / a
    end
   
    bitmap.set_pixel(x, y, color)
  end
end

loop {Graphics.update}[/pre]

bitmap0.zip

6.06 KB, 下载次数: 4

bitmap0.dll 2022/8/7

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部