チュートリアル - ビットマップ ペイント ツールの開発 - エアブラシとシェイプ

このビットマップ ペイント ツール開発の手順では、ツールにエアブラシ オプションと、矩形および円形のブラシで描画するためのブラシ シェイプのオプションを追加します。

全体の流れ:

既存のロールアウトにブラシ シェイプを定義するドロップダウン リスト、エアブラシを使用可能にするチェックボタン、およびエアブラシの吹き付け強度を制御するための編集ボックスを追加します。

既存のコードを拡張し、エアブラシ オプションについては点がランダムに描画されるようにします。

drawStroke 関数を拡張し、[サイズ] (Size)の半径の円を描画できるようにします。

スクリプト:

    macroScript MicroPaint category: "HowTo"
    (
    global MicroPaint_CanvasRollout
    try (destroyDialog MicroPaint_CanvasRollout) catch()
    local isDrawing = false
    local bitmapX = bitmapY = 512
    local theCanvasBitmap = bitmap bitmapX bitmapY color:white
    local currentPos = lastPos = [0,0]

    rollout MicroPaint_CanvasRollout "MicroPaint"
    (
      bitmap theCanvas pos:[0,0] width:bitmapX height:bitmapY bitmap:theCanvasBitmap
      colorpicker inkColor height:16 modal:false color:black across:4
      checkbutton airBrush "AirBrush" width:50
      spinner AirBrushSpeed "Speed" range:[0.1,50,10] fieldwidth:40
      spinner BrushSize "Size" range:[1,50,10] type:#integer fieldwidth:40
      listbox BrushShape items:#("Circle","Box") pos:[bitmapX+5,0]width:90

      fn paintBrush pos =
      (
        case BrushShape.selection of
        (
          1: (
            if distance pos currentPos <= BrushSize.value/2 do
              setPixels theCanvasBitmap pos #(inkColor.color)
          )
          2:  setPixels theCanvasBitmap pos #(inkColor.color)
         )
      )

      fn drawStroke lastPos pos =
      (
        currentPos = lastPos
        deltaX = pos.x - lastPos.x
        deltaY = pos.y - lastPos.y
        maxSteps = amax #(abs(deltaX),abs(deltaY))
        deltaStepX = deltaX / maxSteps
        deltaStepY = deltaY / maxSteps
        for i = 0 to maxSteps do
        (
          if airBrush.checked then
          (
            for b = 1 to (BrushSize.value / AirBrushSpeed.value) do
            paintBrush (currentPos + (random [-BrushSize.value/2,-BrushSize.value/2] [BrushSize.value/2,BrushSize.value/2] ))
          )
          else
            for b = -BrushSize.value/2 to BrushSize.value/2 do
              for c = -BrushSize.value/2 to BrushSize.value/2 do
                paintBrush (currentPos + [c,b])
          currentPos += [deltaStepX, deltaStepY]
        )
        theCanvas.bitmap = theCanvasBitmap
      )

      on MicroPaint_CanvasRollout lbuttondown pos do
      (
        lastPos = pos
        isDrawing = true
        drawStroke lastPos pos
      )
      on MicroPaint_CanvasRollout lbuttonup pos do isDrawing = false
      on MicroPaint_CanvasRollout mousemove pos do
      (
        if isDrawing do drawStroke lastPos pos
        lastPos = pos
      )
    )
    createDialog MicroPaint_CanvasRollout (bitmapx+100) (bitmapy+30)
    )

ステップごとの解説

--Code in italic has no changes since the previous version.
macroScript MicroPaint category:"HowTo"
(
global MicroPaint_CanvasRollout
try(destroyDialog CanvasRollout)catch()
local isDrawing = false
local bitmapX = bitmapY = 512
local theCanvasBitmap = bitmap bitmapX bitmapY color:white
rollout MicroPaint_CanvasRollout "MicroPaint"
(
bitmap theCanvas pos:[0,0] width:bitmapX height:bitmapY bitmap:theCanvasBitmap colorpicker inkColor height:16 modal:false color:black across:4

新しいコントロールを全部、最下部の横一列に自動的に配置できるように、across: パラメータを 4 に増やします。

checkbutton airBrush "AirBrush" width:50

このチェックボタンのチェックマークが付けられると、エアブラシ機能が使えるようになります。

spinner AirBrushSpeed "Speed" range:[0.1,50,10] fieldwidth:40

この値でエアブラシ機能の強度を制御します。

spinner BrushSize "Size" range:[1,50,10] type:#integer fieldwidth:40 listbox BrushShape items:#("Circle", "Box") width:90 pos:[bitmapx+5,0]

このリストボックスでブラシのシェイプを選択します。このコードの後のバージョンでは、ツールをさらに追加します。

Listbox

fn paintBrush pos = ( case BrushShape.selection of (

ブラシ シェイプのドロップダウン リストでの設定によって、ピクセルは円形の中だけで描画されるか、または以前と同じように描画されます。

Case 式

1: (
if distance pos currentPos <= BrushSize.value/2 do
setPixels theCanvasBitmap pos #(inkColor.color)
)

円形のシェイプが選択された場合、描画する位置からブラシの中心までの距離と半径の値 (サイズを 2 で割った値) を比較します。距離が半径より短い場合にのみ、描画を行います。円形のブラシはこうして定義されます。

2: setPixels theCanvasBitmap pos #(inkColor.color)

前の手順で従来使用されていた関数です。ドロップダウン リストで 2 - [ボックス] (Box)が選択された場合に使用されます。

) )
fn drawStroke lastPos pos =
(
currentPos = lastPos
deltaX = pos.x - lastPos.x
deltaY = pos.y - lastPos.y
maxSteps = amax #(abs(deltaX),abs(deltaY))
deltaStepX = deltaX / maxSteps
deltaStepY = deltaY / maxSteps
for i = 0 to maxSteps do
( if airBrush.checked then (

エアブラシ オプションが選択されている場合、次のコードが実行されます。

for b = 1 to (BrushSize.value / AirBrushSpeed.value) do

一定の回数繰り返します。回数はブラシのサイズとエアブラシの[Speed]の値によって決まります。[Speed]の値が高いほど、ブラシのサンプル数は低くなります。

paintBrush (currentPos + (random [-BrushSize.value/2,-BrushSize.value/2] [BrushSize.value/2,BrushSize.value/2] ))

反復のたびに、ボックス ブラシの左下隅と右上隅の間に点をランダムに描画します。円形のブラシが選択されている場合、上述の paintBrush 関数の新しいコードにより、点の一部がフィルタリングされ、描画されません。

)
else

それ以外の場合は、以下の従来のブラシのコードが実行されます。

for b = -BrushSize.value/2 to BrushSize.value/2 do
for c = -BrushSize.value/2 to BrushSize.value/2 do
paintBrush (currentPos + [c,b])
currentPos += [deltaStepX, deltaStepY]
)
theCanvas.bitmap = theCanvasBitmap
)
on MicroPaint_CanvasRollout lbuttondown pos do
(
lastPos = pos
isDrawing = true
drawAPoint lastPos pos
)
on MicroPaint_CanvasRollout lbuttonup pos do isDrawing = false
on MicroPaint_CanvasRollout mousemove pos do
(
if isDrawing do drawAPoint lastPos pos
lastPos = pos
) createDialog MicroPaint_CanvasRollout (bitmapX+100)(bitmapY+30)

カラーとブラシ サイズの新しいユーザ インタフェース コントロールが収まるように、ダイアログ ボックスの横のサイズを 100 ピクセル大きくします。

)

結果:

前のチュートリアル:

チュートリアル - ビットマップ ペイント ツールの開発 - ブラシのサイズとカラー

次のチュートリアル:

チュートリアル - ビットマップ ペイント ツールの開発 - スムーズ ブラシ