| 
 不依赖SEP,插入默认工程应该就可以使用 
提供20个绘图指令,无论如何应该够用了 
 
Q&A: 
Q:这个脚本能用来干什么? 
A:绘制异型血槽(如环状)、绘制能力雷达(六边形战士)、绘制渐变转场中的渐变分隔线、异型透视窗格、等等…… 
Q:绘图指令具体如何调用? 
A:参见脚本前面的说明。 
Q:能用虚线绘制矩形和直线以外的形状吗? 
A:不能。 
Q:为什么可填充的形状中不包括矩形? 
A:参见Bitmap#fill_rect,如果你使用RGD或者SEP Core那么还有Bitmap#gradient_fill_rect 
Q:我想用平行四边形切一个位图传送怎么办?默认只有Bitmap#blt,而你这个插件也只能用正多边形切正方形或者菱形? 
A:请找到四边形的四个顶点,然后调用blt_polygon,所有平行四边形都是多边形的一种。 
Q:我的位图传送后被切边了,不完整? 
A:只有用位图填充,即fill系指令时,你给的位图会被插件自动重复成图案以保证填满。仅单纯的传送不会复制位图,如果你的位图比传送的区域小,尝试使用填充指令而不是传送指令,或者你看看是不是参照点没有写对导致传歪了。 
Q:渐变的效率怎么样? 
A:肯定是不如GDI+,但是比draw_text快,反正你用足够了。 
 
RUBY 代码 
[code]#============================================================================== 
# ■ [Bitmap Canvas] 位图画布处理核心 v1.1 by SailCat 
#------------------------------------------------------------------------------ 
#   方法:本脚本插入Main之前使用 
#   依赖:无 
#   版本:v1.1 (Build 221121) 
#   效果: 
#     1. 可以用简单指令在位图对象上绘制图形,可以绘制从直线到封闭曲线的15种图形 
#     2. 可以用简单指令在位图对象上叠加以不同形状(共5种)剪裁的其他位图 
#   配置:画笔线形的配置 
#   冲突:无 
#   说明: 
#     1. 绘制直线: 
#        draw_line(起始x, 起始y, 结束x, 结束y, 颜色, 线形) 
#     2. 绘制矩形(空心): 
#       a) draw_rect(左上x, 左上y, 长, 宽, 颜色, 线形) 
#       b) draw_rect(矩形, 颜色, 线形) 
#     3. 绘制渐变色直线: 
#        gradient_draw_line(起始x, 起始y, 结束x, 结束y, 颜色1, 颜色2) 
#     4. 绘制路径(连续直线): 
#        draw_path(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 颜色) 
#     5. 绘制多边形(连续封闭直线): 
#        draw_polygon(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 颜色) 
#     6. 绘制正多边形: 
#        draw_isogon(外接圆心x, 外接圆心y, 半径, 边数, 旋转角, 颜色) 
#     7. 绘制椭圆: 
#        draw_ellipse(圆心x, 圆心y, 半横径,半纵径, 颜色) 
#     8. 绘制圆: 
#        draw_circle(圆心x, 圆心y, 半径,颜色) 
#     9. 绘制曲线: 
#        draw_curve(起始x, 起始y, 中继点Ax, 中继点Ay, 中继点Bx, 中继点By[, 
#          中继点Cx, 中继点Cy[, ...]], 结束x, 结束y, 颜色) 
#     10. 绘制封闭曲线: 
#        draw_closed_curve(点1x, 点1y, 中继1Ax, 中继1Ay, 中继1Bx, 中继1By, 
#          点2x, 点2y[, 中继2Ax, 中继2Ay, 中继2Bx, 中继2By, 点3x, 点3y[, ...]], 
#          颜色) 
#     11.填涂多边形: 
#       a) fill_polygon(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 边框颜色[, 
#          填充颜色1[, 填充颜色2[, 渐变方向]]]) 
#       b) fill_polygon(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 边框颜色, 
#          填充位图[, 不透明度]) 
#     12.填涂正多边形: 
#       a) fill_isogon(外接圆心x, 外接圆心y, 半径, 边数, 旋转角, 边框颜色[, 
#          填充颜色1[, 填充颜色2[, 渐变方向]]]) 
#       b) fill_isogon(外接圆心x, 外接圆心y, 半径, 边数, 旋转角, 边框颜色, 
#          填充位图[, 不透明度]) 
#     13.填涂椭圆: 
#       a) fill_ellipse(圆心x, 圆心y, 半横径,半纵径, 边框颜色[, 填充颜色1[, 
#          填充颜色2[, 渐变方向]]]) 
#       b) fill_ellipse(圆心x, 圆心y, 半横径,半纵径, 边框颜色, 填充位图[, 
#          不透明度]) 
#     14.填涂圆: 
#       a) fill_circle(圆心x, 圆心y, 半径,边框颜色[, 填充颜色1[, 填充颜色2[, 
#          渐变方向]]]) 
#       b) fill_circle(圆心x, 圆心y, 半径,边框颜色, 填充位图[, 不透明度]) 
#     15.填涂封闭曲线: 
#       a) fill_closed_curve(点1x, 点1y, 中继1Ax, 中继1Ay, 中继1Bx, 中继1By, 
#          点2x, 点2y[, 中继2Ax, 中继2Ay, 中继2Bx, 中继2By, 点3x, 点3y[, ...]], 
#          边框颜色[, 填充颜色1[, 填充颜色2[, 渐变方向]]]) 
#       b) fill_closed_curve(点1x, 点1y, 中继1Ax, 中继1Ay, 中继1Bx, 中继1By, 
#          点2x, 点2y[, 中继2Ax, 中继2Ay, 中继2Bx, 中继2By, 点3x, 点3y[, ...]], 
#          边框颜色, 填充位图[, 不透明度]) 
#     16.传送多边形: 
#        blt_polygon(点1x, 点1y, 点2x, 点2y, 点3x, 点3y[, ...], 源位图, 
#          参考点1x, 参考点1y[, 不透明度]) 
#     17.传送正多边形: 
#        blt_isogon(外接圆心x, 外接圆心y, 半径, 边数, 旋转角, 源位图, 参考心x, 
#          参考心y[, 不透明度]) 
#     18.传送椭圆: 
#        blt_ellipse(圆心x, 圆心y, 半横径,半纵径, 源位图, 参考心x, 参考心y[, 
#          不透明度]) 
#     19.传送圆: 
#        blt_circle(圆心x, 圆心y, 半径,源位图, 参考心x, 参考心y[, 不透明度]) 
#     20.传送封闭曲线: 
#        blt_closed_curve(点1x, 点1y, 中继1Ax, 中继1Ay, 中继1Bx, 中继1By, 
#          点2x, 点2y[, 中继2Ax, 中继2Ay, 中继2Bx, 中继2By, 点3x, 点3y[, ...]], 
#          源位图, 参考点1x, 参考点1y[, 不透明度]) 
#============================================================================== 
#============================================================================== 
# ■ SailCat's 插件公用 
#============================================================================== 
module SailCat 
  #-------------------------------------------------------------------------- 
  # ● 脚本配置区 
  #-------------------------------------------------------------------------- 
  module Canvas_Config 
    CANVAS_LINE_DOTTED = [1, 0]               # 点线画笔 
    CANVAS_LINE_DASHED = [1, 1, 0, 1]         # 短虚线画笔 
    CANVAS_LINE_LONGDASH = [1, 1, 0, 0, 1, 1]# 长虚线画笔 
    CANVAS_LINE_DASHDOT = [1, 0, 1, 1, 1, 0]  # 点划线画笔 
    CANVAS_LINE_BROKEN = [1, 0, 0]            # 散点画笔 
  end 
end 
 
#============================================================================== 
# ■ Bitmap 
#============================================================================== 
class Bitmap 
  includeSailCat::Canvas_Config 
  #-------------------------------------------------------------------------- 
  # ● 常量 
  #-------------------------------------------------------------------------- 
  CANVAS_LINE_SOLID = [1]                     # 实心画笔,该常量禁止修改配置 
  #-------------------------------------------------------------------------- 
  # ● 绘制直线 
  #     x1 : 起始的 X 坐标 
  #     y1 : 起始的 Y 坐标 
  #     x2 : 结束的 X 坐标 
  #     y2 : 结束的 Y 坐标 
  #     color : 直线的颜色 (Color) 
  #     style : 直线的线型 
  #-------------------------------------------------------------------------- 
  def draw_line(x1, y1, x2, y2, color, style = CANVAS_LINE_SOLID) 
    return set_pixel(x1, y1, color)if x1 == x2 and y1 == y2 
    dx = (x2 - x1).abs 
    dy = (y2 - y1).abs 
    x = x1 
    y = y1 
    rx = x2 - x1  0 
    ry = y2 - y1  0 
    b_index = 0 
    b_size = style.size 
    if dx == 0and style == CANVAS_LINE_SOLID 
      fill_rect(x1, [y1, y2].min, 1, dy + 1, color) 
    elsif dy == 0and style == CANVAS_LINE_SOLID 
      fill_rect([x1, x2].min, y1, dx + 1, 1, color) 
    elsif dx  yk 
          yj += 1 
          xj += dx 
        end 
        edges[yj] ||= [] 
        edges[yj].push([xj, dx, yi]) 
      end 
    end 
    returnunless max_y - min_y > 1and max_x - min_x > 1 
    dw = max_x - min_x - 1 
    dh = max_y - min_y - 1 
    if fill_mode == 0 
      if fill1 != fill2 
        dr = (fill2.red - fill1.red) / dh 
        dg = (fill2.green - fill1.green) / dh 
        db = (fill2.blue - fill1.blue) / dh 
        da = (fill2.alpha - fill1.alpha) / dh 
        gradient = true 
      end 
      f = fill1.clone 
      aet = edges[min_y].each{|edge| edge[0] += edge[1]}.sort! 
      for y in min_y + 1..max_y - 1 
        aet.concat(edges[y]).sort! if edges[y] 
        0.step(aet.size - 2, 2)do |i| 
          xi = aet[0].round 
          xj = aet[i + 1][0].round 
          xi += 1until xi == width - 1or get_pixel(xi, y) != color 
          xj -= 1until xj == 0or get_pixel(xj, y) != color 
          fill_rect(xi, y, xj - xi + 1, 1, f)if xj >= xi 
        end 
        aet.reject! {|edge| edge[2] == y} 
        aet.each{|edge| edge[0] += edge[1]}.sort! 
        f.set(f.red + dr, f.green + dg, f.blue + db, f.alpha + da)if gradient 
      end 
    else 
      if fill_mode == 2 
        src = Bitmap.new(dw, fill_pattern.height) 
        0.step(dw - 1, fill_pattern.width)do |x| 
          src.blt(x, 0, fill_pattern, fill_pattern.rect, fill_opacity) 
        end 
      else 
        src = Bitmap.new(dw, 1) 
        src.gradient_draw_line(0, 0, dw - 1, 0, fill1, fill2) 
      end 
      ox = -1 - min_x 
      y_index = 0 
      aet = edges[min_y].each{|edge| edge[0] += edge[1]}.sort! 
      for y in min_y + 1..max_y - 1 
        aet.concat(edges[y]).sort! if edges[y] 
        0.step(aet.size - 2, 2)do |i| 
          xi = aet[0].round 
          xj = aet[i + 1][0].round 
          xi += 1until xi == width - 1or get_pixel(xi, y) != color 
          xj -= 1until xj == 0or get_pixel(xj, y) != color 
          blt(xi, y, src, Rect.new(xi + ox, y_index, xj - xi + 1, 1)) 
        end 
        aet.reject! {|edge| edge[2] == y} 
        aet.each{|edge| edge[0] += edge[1]}.sort! 
        y_index = (y_index + 1) % src.height 
      end 
      src.dispose 
    end 
  end 
  #-------------------------------------------------------------------------- 
  # ● 传送位图多边形 
  #     x1 : 第一点的 X 坐标 
  #     y1 : 第一点的 Y 坐标 
  #     x2 : 第二点的 X 坐标 
  #     y2 : 第二点的 Y 坐标 
  #     x3 : 第三点的 X 坐标 
  #     y3 : 第三点的 Y 坐标 
  #     args : 后续的参数(加多个点,最后是位图, 偏移x,偏移y,(可选)不透明度) 
  #            偏移x和偏移y的位置参考第一个点 
  #-------------------------------------------------------------------------- 
  def blt_polygon(x1, y1, x2, y2, x3, y3, *args) 
    if args[-3].is_a?(Bitmap) 
      src, x0, y0 = args[-3, 3] 
      opacity = 255 
      nodes = [x1, y1, x2, y2, x3, y3].concat(args[0...-3]) 
    elsif args[-4].is_a?(Bitmap) 
      src, x0, y0, opacity = args[-4, 4] 
      nodes = [x1, y1, x2, y2, x3, y3].concat(args[0...-4]) 
    else 
      raiseArgumentError 
    end 
    raiseArgumentErrorunless nodes.size[0] == 0 
    edges = {} 
    min_y = height 
    max_y = 0 
    ox = x0 - x1 
    oy = y0 - y1 
    0.step(nodes.size - 2, 2)do |i| 
      xi, yi = nodes[i, 2] 
      min_y = [min_y, yi].min 
      max_y = [max_y, yi].max 
      xj, yj = nodes[(i + 2) % nodes.size, 2] 
      dx = 1.0 * (xi - xj) / (yi - yj) 
      if yi < yj 
        delta = -1 
        delta -= 2until(yh = nodes[(i + delta) % nodes.size]) != yi 
        if yh < yi 
          yi += 1 
          xi += dx 
        end 
        edges[yi] ||= [] 
        edges[yi].push([xi, dx, yj]) 
      elsif yi > yj 
        delta = 5 
        delta += 2until(yk = nodes[(i + delta) % nodes.size]) != yj 
        if yj > yk 
          yj += 1 
          xj += dx 
        end 
        edges[yj] ||= [] 
        edges[yj].push([xj, dx, yi]) 
      end 
    end 
    aet = [] 
    for y in min_y..max_y 
      aet.concat(edges[y]).sort! if edges[y] 
      0.step(aet.size - 1, 2)do |i| 
        xi = aet[0].round 
        xj = aet[i + 1][0].round 
        blt(xi, y, src, Rect.new(xi + ox, y + oy, xj - xi + 1, 1), opacity) 
      end 
      aet.reject! {|edge| edge[2] == y} 
      aet.each{|edge| edge[0] += edge[1]}.sort! 
    end 
  end 
  #-------------------------------------------------------------------------- 
  # ● 绘制正多边形 
  #     x : 正多边形外接圆心 X 坐标 
  #     y : 正多边形外接圆心 Y 坐标 
  #     rad : 正多边形外接圆 半径 
  #     edges : 正多边形的边数 
  #     angle : 正多边形旋转角度 
  #     color : 正多边形的颜色 (Color) 
  #-------------------------------------------------------------------------- 
  def draw_isogon(x, y, rad, edges, angle, color) 
    raiseArgumentErrorif edges < 3 
    step = Math::PI * 2 / edges 
    args = [] 
    angle_i = Math::PI * (270 + angle) / 180 
    edges.timesdo 
      args.push((x + rad * Math.cos(angle_i)).round, 
        (y + rad * Math.sin(angle_i)).round) 
      angle_i += step 
    end 
    draw_polygon(*args.push(color)) 
  end 
  #-------------------------------------------------------------------------- 
  # ● 绘制实心正多边形 
  #     x : 正多边形外接圆心 X 坐标 
  #     y : 正多边形外接圆心 Y 坐标 
  #     rad : 正多边形外接圆 半径 
  #     edges : 正多边形的边数 
  #     angle : 正多边形旋转角度 
  #     color : 边框的颜色 (Color) 
  #     fill : 填充选项,具体的填充选项有: 
  #            2个颜色 + true/false : 两个颜色以垂直/水平方式渐变填充 
  #            2个颜色 : 两个颜色以水平方向渐变填充 
  #            1个颜色 : 实心填充 
  #            位图 + 数值 : 以位图图案填充,数值为不透明度 
  #            位图 : 以位图图案填充,不透明度固定为255 
  #            省略 : 用边框色实心填充 
  #-------------------------------------------------------------------------- 
  def fill_isogon(x, y, rad, edges, angle, color, *fill) 
    raiseArgumentErrorif edges < 3 
    step = Math::PI * 2 / edges 
    args = [] 
    angle_i = Math::PI * (270 + angle) / 180 
    edges.timesdo 
      args.push((x + rad * Math.cos(angle_i)).round, 
        (y + rad * Math.sin(angle_i)).round) 
      angle_i += step 
    end 
    fill_polygon(*args.push(color).concat(fill)) 
  end 
  #-------------------------------------------------------------------------- 
  # ● 传送位图正多边形 
  #     x : 正多边形外接圆心 X 坐标 
  #     y : 正多边形外接圆心 Y 坐标 
  #     rad : 正多边形外接圆 半径 
  #     edges : 正多边形的边数 
  #     angle : 正多边形旋转角度 
  #     src_bitmap : 传送元位图 
  #     x0 : 传送圆心 X 坐标 
  #     y0 : 传送圆心 Y 坐标 
  #     opacity : 不透明度 
  #-------------------------------------------------------------------------- 
  def blt_isogon(x, y, rad, edges, angle, src_bitmap, x0, y0, opacity = 255) 
    raiseArgumentErrorif edges < 3 
    step = Math::PI * 2 / edges 
    args = [] 
    angle_i = Math::PI * (270 + angle) / 180 
    edges.timesdo 
      args.push((x + rad * Math.cos(angle_i)).round, 
        (y + rad * Math.sin(angle_i)).round) 
      angle_i += step 
    end 
    args.push(src_bitmap, x0 - x + args[0], y0 - y + args[1], opacity) 
    blt_polygon(*args) 
  end 
  #-------------------------------------------------------------------------- 
  # ● 绘制圆 
  #     x : 圆心 X 坐标 
  #     y : 圆心 Y 坐标 
  #     rad : 半径 
  #     color : 圆的颜色 (Color) 
  #-------------------------------------------------------------------------- 
  def draw_circle(x, y, rad, color) 
    draw_ellipse(x, y, rad, rad, color) 
  end 
  #-------------------------------------------------------------------------- 
  # ● 绘制椭圆 
  #     x : 圆心 X 坐标 
  #     y : 圆心 Y 坐标 
  #     rad_x : 水平半径 
  #     rad_y : 垂直半径 
  #     color : 椭圆的颜色 (Color) 
  #-------------------------------------------------------------------------- 
  def draw_ellipse(x, y, rad_x, rad_y, color) 
    fill_ellipse(x, y, rad_x, rad_y, color, nil) 
  end 
  #-------------------------------------------------------------------------- 
  # ● 绘制实心圆 
  #     x : 圆心 X 坐标 
  #     y : 圆心 Y 坐标 
  #     rad : 半径 
  #     border_color : 圆的边框颜色 (Color) 
  #     fill : 填充选项,具体的填充选项有: 
  #            nil : 不填充 
  #            2个颜色 + true/false : 两个颜色以垂直/水平方式渐变填充 
  #            2个颜色 : 两个颜色以水平方向渐变填充 
  #            1个颜色 : 实心填充 
  #            位图 + 数值 : 以位图图案填充,数值为不透明度 
  #            位图 : 以位图图案填充,不透明度固定为255 
  #            省略 : 用边框色实心填充 
  #-------------------------------------------------------------------------- 
  def fill_circle(x, y, rad, border_color, *fill) 
    fill_ellipse(x, y, rad, rad, border_color, *fill) 
  end 
  #-------------------------------------------------------------------------- 
  # ● 绘制实心椭圆 
  #     x : 圆心 X 坐标 
  #     y : 圆心 Y 坐标 
  #     rad_x : 水平半径 
  #     rad_y : 垂直半径 
  #     border_color : 椭圆的边框颜色 (Color) 
  #     fill : 填充选项,具体的填充选项有: 
  #            nil : 不填充 
  #            2个颜色 + true/false : 两个颜色以垂直/水平方式渐变填充 
  #            2个颜色 : 两个颜色以水平方向渐变填充 
  #            1个颜色 : 实心填充 
  #            位图 + 数值 : 以位图图案填充,数值为不透明度 
  #            位图 : 以位图图案填充,不透明度固定为255 
  #            省略 : 用边框色实心填充 
  #-------------------------------------------------------------------------- 
  def fill_ellipse(x, y, rad_x, rad_y, border_color, *fill) 
    raiseArgumentErrorif rad_x < 0or rad_y < 0 
    return set_pixel(x, y, border_color)if rad_x == 0and rad_y == 0 
    return fill_rect(x - rad_x, y, rad_x   |