mieki256's diary



2021/10/01(金) [n年前の日記]

#1 [cg_tools] ImageMagickで実験中

数字が書かれただけの画像を大量に作ってスプライトシートにしたい。ImageMagick を使えばできるかなと思って実験してるのだけど、大量の画像をタイル状に並べて結合する段階でハマっているところ。

何故か各画像の下にファイル名っぽいものが描画された状態で結合されてしまう。以前試したときはそういう症状が出なかったのだけどなあ…。

2021/10/02() [n年前の日記]

#1 [cg_tools][python] 数字が書かれた画像をたくさん作りたい

数字が書かれた画像を ―― 「0000」から「00xx」まで連番が書かれた感じの画像を複数作りたい。ImageMagick を使えばできるんじゃないかと思えてきたので試してみた。

環境は、Windows10 x64 21H1 + Python 3.9.5 64bit + ImageMagick 7.1.0-5 Q16 x64。

数字を描画。 :

以下のページで、ImageMagick を使って画像に文字を描画する方法が説明されてたので参考にして作業。ありがたや。

_ImageMagickで画像に文字を描画 - エラーの向こうへ

まず、指定できるフォントの種類を把握しないといけない。.ttf を指定することでもいいらしいけど…。とりあえず、以下を打てば利用できるフォントの一覧を表示できるらしい。大量にずらずらと出てきたのでテキストファイルに書き込んでエディタで参照。
magick convert -list font

magick convert -list font > fontlist.txt

実際に文字を描画してみる。以下の指定で、96x96 の画像サイズの真ん中に、「Sample」という文字を描画できる。
magick convert -size 96x96 -gravity center -font Arial-Black -fill white -background gray -pointsize 32 label:Sample output.png
  • -size 96x96 : 画像サイズを指定。
  • -gravity center : 画像の真ん中の位置を指定。
  • -font Arial-Black : Arial-Blackフォントを指定。
  • -fill white : 色は白で描画。
  • -background gray : 背景色を灰色に。
  • -pointsize 32 : フォントの文字サイズを指定。
  • label:Sample : 「Sample」という文字列を描画させる。

背景を透明にして描画したい場合は以下。
magick convert -size 96x96 -gravity center -font Inconsolata-Bold -fill black -background rgba(0,0,0,0) -pointsize 32 label:0000 png32:output.png
  • -background rgba(0,0,0,0) : 背景を透明化。もしかすると -background none でもいいのだろうか。
  • png32:output.png : 出力ファイル名の先頭に png32: を追加してアルファチャンネルを含むpng画像として出力することを明示。

これで、一枚だけ作るやり方は分ったので、スクリプトを書いて大量に生成してみたい。

今回は、make_seq_img.py というPythonスクリプトを書いて、0000 - 0063 までの数字が書かれた64枚の画像を out/ ディレクトリに出力するようにしてみた。

_make_seq_img.py
import os
import subprocess

mgk = "magick convert"

size = "-size 96x96"
pos = "-gravity center"
font = "-font Inconsolata-Bold"
col = "-fill black"
bg = "-background rgba(0,0,0,0)"
pt = "-pointsize 40"

for i in range(8 * 8):
    lbl = "%04d" % i
    fn = "png32:out/%04d.png" % i
    cmd = f"{mgk} {size} {pos} {font} {col} {bg} {pt} label:{lbl} {fn}"
    subprocess.call(cmd)
    print("Output: %s" % fn)

Python では、subprocess.call(文字列) で外部プログラムを実行することができるらしい。

以下で実行。
mkdir out
python make_seq_img.py

タイル状に並べて結合したいが上手く行かない。 :

これで大量の画像が生成できたので、タイル状に並べて結合してスプライトシートっぽくしてみたい。

そういった処理も ImageMagick で出来たはず、なのだけど…。

magick montage -geometry +0+0 -background none out/*.png spritesheet.png

これが上手く行かない。各画像の下に、何故かファイル名っぽいものが描き込まれてしまう。何だコレ。

spritesheet_0.png


どうやら label なるものが描き込まれてしまっているらしい…。

-label "" (*NIX の場合は -label '' だろうか)をつけることで、label を描かない指定ができるらしいのだけど…。

magick montage -geometry +0+0 -background none -label "" out/*.png spritesheet.png

spritesheet_1.png

たしかに label は無くなったけど、これでもまだ結果としてはよろしくない。96 x 96ドットの画像を 8 x 8個並べてるから、768 x 768ドットの画像になるはずだけど、実際は 768 x 912ドットになってしまっている。縦方向に余計な隙間が入ってるわけで。何だコレ。

以下のページを眺めてみたけど、解決方法は見つからず。

_Montage -- IM v6 Examples

以下のやりとりを眺めて、状況が分かってきた。数字画像を作成する際に label を指定したものだから、生成された画像のメタデータにも label 情報が残っていて、「この画像は label を持っている画像だな。では label も描き込まねば」と処理されてしまうようで。label を持った画像を扱うと、-label "" や -set label "" を指定しても label 用の描画領域が含まれてしまうのだとか。しかも、簡単な解決策は無いらしい。

_ImageMagick montage always includes labels - Stack Overflow

Python + Pillow でタイル状に並べて結合。 :

仕方ないので、ImageMagick で結合するのは諦めて、Python 3.9.5 64bit + Pillow 8.3.2 で画像結合するスクリプトを書いた。スクリプト内にマジックナンバーがその他が列挙されちゃってるけど…。まあ、処理ができればいいか…。

_joint_image.py
from PIL import Image, ImageFilter
import glob

inputfiles = "out/*.png"
output = "output.png"
xloop = 8

l = sorted(glob.glob(inputfiles))

w, h = 0, 0
imgs = []
for s in l:
    im = Image.open(s)
    if im.size[0] > w:
        w = im.size[0]
    if im.size[1] > h:
        h = im.size[1]
    imgs.append(im)

yloop = len(l) // xloop
if len(l) % xloop != 0:
    yloop += 1

tw = w * xloop
th = h * yloop
nim = Image.new("RGBA", (tw, th), (0, 0, 0, 0))

xi, yi = 0, 0
idx = 0
while yi < yloop:
    x, y = xi * w, yi * h
    nim.paste(imgs[idx].copy(), (x, y))
    idx += 1
    if idx >= len(l):
        break
    
    xi += 1
    if xi >= xloop:
        xi = 0
        yi += 1

nim.save(output)

output.png
_output.png

一応これで、数字が書かれている画像をタイル状に並べることができた。

GIMP 2.10.22 x64 Portable samj版を使って、背景に少し模様っぽいものも追加してみた。96 x 96 ドットの画像を作ってから、フィルタ → カラーマッピング → 並べる、で、800% x 800% にして並べて、前述の画像と重ね合わせた。

以下が完成画像。CC0 / Public Domain ってことで。まあ、どこでこんなの使うんだよって感じだけど…。

spritesheet_number.png
_spritesheet_number.png

ということで、ImageMagick の挙動でハマったものの、なんとか目的は果たせた。

それにしても、結局 Python スクリプトを書いて対応したわけだから…。だったら最初から、数字を描き込む処理も含めて、全部 Python + Pillow で処理してしまえばよかったのではないか…な…。

#2 [pygame] Pyagmeで画像を分割して描画

Python + Pygame で、スプライトシート画像を読み込んで、各パーツに分割してウインドウ内に描画したい。考えてみたら、今までそういう処理は試してなかったな…。さて、どうすれば…。

環境は、Windows10 x64 21H1 + Python 3.9.5 64bit + pygame 2.0.1。

使用画像は以下。

_spritesheet_number.png

blit()を使う方法。 :

Pygame は、Surface.blit() を使うことで、Surface から Surface へと画像を転送することができる。この blit() に pygame.Rect という矩形範囲を渡すことで、元画像の任意の範囲だけを転送、ということができるらしい。

これを使えばスプライトシート画像の一部だけを抜き出して描画できるんじゃないかな…。ということで、試してみた。

_02_blit_mn.py
import pygame
import sys

SCRW, SCRH = 320, 240

pygame.init()
screen = pygame.display.set_mode((SCRW, SCRH), pygame.DOUBLEBUF)

imgname = "spritesheet_number.png"
img = pygame.image.load(imgname).convert_alpha()

# make split area list
rects = []
w, h = 96, 96
for y in range(8):
    for x in range(8):
        rects.append(pygame.Rect(x * w, y * h, w, h))

index = 0
running = True

clock = pygame.time.Clock()

# Main loop
while running:

    # check event
    for ev in pygame.event.get():
        if ev.type == pygame.QUIT:
            running = False
        if ev.type == pygame.KEYDOWN:
            if ev.key == pygame.K_ESCAPE or ev.key == pygame.K_q:
                # Push ESC or Q key
                running = False
                
    screen.fill((40, 60, 200))   # clear screen

    # draw image
    x = 160 - 96 / 2
    y = 120 - 96 / 2
    screen.blit(img, (x, y), area=rects[index])

    index = (index + 1) % len(rects)

    pygame.display.flip()
    clock.tick_busy_loop(60)
    
    cap = "Image Split - %5.2f FPS" % (clock.get_fps())
    pygame.display.set_caption(cap)

pygame.quit()
sys.exit()

pygame.Rect(x, y, width, height) で矩形範囲を指定できる。それを配列 rects に蓄えておいて…。スクリーンに相当する Surface、を格納している screen に blit() で描画する際に、area=rects[index] という形で渡して、「元画像の、この範囲だけを抜き出して描画せよ」的な処理をしている。

実行したら、こうなった。

02_blit_mn_ss01.gif

元画像の一部だけを描画できている。

ということで、blit() に pygame.Rect を渡せば、目的は果たせると分かった。

ちなみに、上記のスクリプトでは pygame.Rect() を使ってるけど、その後ググってみたら、blit(img, (px, py), (x, y, w, h)) という書き方もできると知った。

# make split area list
rects = []
w, h = 96, 96
for y in range(8):
    for x in range(8):
        rects.append((x * w, y * h, w, h))
# ...

    # draw image
    x = 160 - 96 / 2
    y = 120 - 96 / 2
    screen.blit(img, (x, y), rects[index])

処理速度で違いはあったりするのかな…。どうなんだろう。

subsurface() を使う方法。 :

Pygame の Surface には、subsurface() というメソッドがあって、コレを使うと、元画像の一部を新たな Surface として得ることができるらしい。引数として、やはり pygame.Rect を渡す模様。

ということで試してみた。

_03_subsurface.py
import pygame
import sys

SCRW, SCRH = 320, 240

pygame.init()
screen = pygame.display.set_mode((SCRW, SCRH), pygame.DOUBLEBUF)

imgname = "spritesheet_number.png"
img = pygame.image.load(imgname).convert_alpha()

# make subsurface
imgs = []
w, h = 96, 96
for y in range(8):
    for x in range(8):
        _rect = pygame.Rect(x * w, y * h, w, h)
        imgs.append(img.subsurface(_rect))

index = 0
running = True

clock = pygame.time.Clock()

# Main loop
while running:

    # check event
    for ev in pygame.event.get():
        if ev.type == pygame.QUIT:
            running = False
        if ev.type == pygame.KEYDOWN:
            if ev.key == pygame.K_ESCAPE or ev.key == pygame.K_q:
                # Push ESC or Q key
                running = False
                
    screen.fill((40, 60, 200))   # clear screen

    # draw image
    x = 160 - 96 / 2
    y = 120 - 96 / 2
    screen.blit(imgs[index], (x, y))

    index = (index + 1) % len(imgs)

    pygame.display.flip()
    clock.tick_busy_loop(60)
    
    cap = "Image Split - %5.2f FPS" % (clock.get_fps())
    pygame.display.set_caption(cap)

pygame.quit()
sys.exit()

Rect を配列に蓄える代わりに、subsurface を配列 imgs に蓄えている。また、screen に blit() で描画する際、元画像として subsurface を渡している。

実行したら、こうなった。

03_subsurface_ss01.gif

ということで、subsurface を使っても、元画像の一部を切り出した感じで描画できると分かった。

ただ、Surface のドキュメントを読むと、ハードウェア描画がどうのこうの、みたいなことが書いてあるような…。

_pygame.Surface - pygame v2.0.1.dev1 documentation

ディスプレイモードがハードウェア描画じゃない場合は、表示に使ってる Surface から subsurface を作ることもできる、と言ってるのかな…。逆に言うと、ハードウェア描画の場合は表示に使ってる Surface から subsurface を作れませんよ、ということだろうな…。

2021/10/03() [n年前の日記]

#1 [cg_tools] ドット絵を弄ってる

道路のパターンを描いたドット絵の並びを弄ってるところ。

マップエディタ Tiled でそこそこ配置した後で、元画像となるタイル(?)画像の並びを弄ろうとしたものだから、面倒臭いことになっていて…。

Tiled のタイルセットウインドウ上で、Ctrl + クリックで2つのタイルを選んでから、右クリックメニュー → タイルの交換、を選べば、マップ上に配置済みの指定タイルを別のタイルで置き換えることができるのだけど…。位置を変更したタイルが1つや2つじゃないものだから、一つ一つ「タイルの交換」を選んでいると時間がかかってしょうがない…。

マップ上のタイルについて、ID min - ID max に対して任意の値を加算・減算、みたいな機能があれば楽になりそうだけど…。そういう機能、もしくはプラグインは無いのだろうか。

いやまあ、マップを作成した後で、タイルセット上のタイルの配置を変更するという行為がおかしいのかもしれんけど。

2021/10/04(月) [n年前の日記]

#1 [pygame] PygameでタイルマップBGを描画

Python + Pygame でタイルマップのBGを描画できるか試してみた。

環境は、Windows10 x64 21H1 + Python 3.9.7 64bit + Pygame 2.0.1。

こんな感じになった。800x600ドットのウインドウ上で描画。カーソルキー、あるいはWASDキーでスクロールができる。




手抜きをして、タイルチップ単位 = 8x8ドット単位でスクロールさせてるから、一般的な2Dゲームのようにドット単位で動かすにはもうちょっとアレコレ処理を入れないといかんのだけど…。でもまあ、とりあえず、Pygame を使った場合でも、こういった描画はできそうだと分かった。

ただ、このやり方では、1280x720のウインドウサイズで描画した際に60FPSにならなかった…。AMD Ryzen 7 1700 (3GHz,8コア,16スレッド) + GeForce GTX 1060 6GB の環境で、2D、しかもBGを1枚しか表示してないのに、60FPSが出ないのはダメだよな…。相変わらず、Python + Pygame は遅い…。

もっとも、8x8ドット単位で処理してるのがいかんのではという気もする。32x32ドットや64x64ドットにして、ループ回数を減らすべきかも。もしくは、BG描画用の大きな Surface を用意して、スクロールに応じて書き換えが必要な部分だけ変更して、ウインドウへの描画はそのBG用Surfaceを使って行う、てな感じの処理にすれば負荷が違ってくるのかもしれない。

ソースと使用画像。 :

ソースは以下。

_02_tilemapbg.py
import json
import pygame
import sys

SCRW, SCRH = 800, 600

pygame.init()
screen = pygame.display.set_mode((SCRW, SCRH), pygame.DOUBLEBUF)

# load Tiled json file
bglayout = "road_layout.json"
with open(bglayout, 'r') as f:
    data = json.load(f)

map_w = int(data["width"])
map_h = int(data["height"])
tile_w = int(data["tilewidth"])
tile_h = int(data["tileheight"])

# get tilemap, convert start ID 1 to 0.
bgtilemap = list(map(lambda x: x-1, data["layers"][0]["data"]))

# load bg chip image
imgname = "road_chip.png"
img = pygame.image.load(imgname).convert_alpha()

# split bg chip image
bgchips = []
w, h = tile_w, tile_h
xc = img.get_width() // w
yc = img.get_height() // h
for yi in range(yc):
    for xi in range(xc):
        x, y = xi * w, yi * h
        bgchips.append(img.subsurface(pygame.Rect(x, y, w, h)))

xofs, yofs = 0, 0
xofs_max = max(0, map_w - (SCRW // tile_w))
yofs_max = max(0, map_h - (SCRH // tile_h))

running = True

clock = pygame.time.Clock()

# Main loop
while running:

    # update
    
    # check event
    for ev in pygame.event.get():
        if ev.type == pygame.QUIT:
            running = False
        if ev.type == pygame.KEYDOWN:
            if ev.key == pygame.K_ESCAPE or ev.key == pygame.K_q:
                # Push ESC or Q key
                running = False

    # scroll BG
    pygame.event.pump()
    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_LEFT] or pressed[pygame.K_a]:
        xofs -= 1
        if xofs < 0:
            xofs = 0
    if pressed[pygame.K_RIGHT] or pressed[pygame.K_d]:
        xofs += 1
        if xofs > xofs_max:
            xofs = xofs_max
    if pressed[pygame.K_UP] or pressed[pygame.K_w]:
        yofs -= 1
        if yofs < 0:
            yofs = 0
    if pressed[pygame.K_DOWN] or pressed[pygame.K_s]:
        yofs += 1
        if yofs > yofs_max:
            yofs = yofs_max

    # draw start
    screen.fill((40, 60, 200))   # clear screen

    # draw tilemap BG
    xc = SCRW // tile_w
    yc = SCRH // tile_h
    for yi in range(yc):
        for xi in range(xc):
            xii = xi + xofs
            yii = yi + yofs
            if xii >= map_w or yii >= map_h:
                continue
            i = bgtilemap[yii * map_w + xii]
            x = xi * tile_w
            y = yi * tile_h
            screen.blit(bgchips[i], (x, y))

    pygame.display.flip()
    clock.tick_busy_loop(60)
    
    cap = "Tilemap BG - %5.2f FPS" % (clock.get_fps())
    pygame.display.set_caption(cap)

pygame.quit()
sys.exit()

処理としては、以下のようなことをしている。
  • マップエディタ Tiled からエクスポートした json を読み込んで、タイルマップの配列(一次元配列)を得る。
  • タイルセット画像を読み込んで、8x8ドット単位で分割。
  • タイルマップ配列に基づいて、8x8ドット単位で、タイルセット画像を描画。

使用画像は以下。

road_chip.png
_road_chip.png

読み込むタイルマップデータ(.json)は以下。Tiled で配置して、json でエクスポートした。

_road_layout.json

Tiled で編集し直したい場合は、以下の Tiled用ファイルを使えばよいかと…。

_road_layout.tmx
_road_chip.json

ソース、画像、Tiled用ファイルは、CC0 / Public Domain ってことで。

余談。今後の課題。 :

こういった感じのタイルマップを自動生成できるようにしたいのだけど、さて、何をどうすればいいのやら。うーん。

道路の自動生成ができれば、道路が無い部分にビルを配置することだってできそうだなと。更に、2Dで道路やビルを配置できるなら、ソレを3Dで処理して…。例えば blender + Python で、道路+ビル街を生成するスクリプトを書けたりしないかなと。要するに、POV-Ray 用の CityGen みたいなことができないかと。

いやまあ、blenderなら、めっちゃリアルでゴイスなビル街を生成してくれる有償アドオンがあるらしいのだけど…。

_Blender の都市生成アドオン「SceneCity」 - 100光年ダイアリー
_SceneCity: 3D city generator addon for Blender 2.9+

この手のツール、アドオン、プラグインは結構作られているようで…。

_3Dソフトで都市を自動生成 - 100光年ダイアリー

ゴイスな映像を作りたいなら、買って使ったほうが早いはず。

2021/10/05(火) [n年前の日記]

#1 [python][pygame] 道路の自動生成処理ができないか試してる

Python + Pygame を使って、2D的なマップ上で道路の自動生成ができないか試しているところ。グリッド上でマス目を埋めていく感じで道路のタイルを置いていくことができないかと。

ただ、これがなかなか上手く行かない…。

処理としては、前、左90度、右90度しか方向を選べないロードローラーが、ランダムな回数分マス目を埋めて、方向を変えてまた進んで、みたいな感じなのだけど。要はタートルグラフィックスみたいなノリで…。

ただ、方向転換タイルや交差点タイルの検出が面倒臭くなってきて…。道路タイルを置くタイミングで交差点等の検出をするのを諦めて、ひとまず一旦全部の道を引いてしまった後で、マップをスキャンして交差点等になりそうな部分を見つけたらタイルを置き換える、という安易な処理を書き始めたのだけど…。このやり方だと、検出・置換すべきパターンがどんどん増えていってしまって…。どうもこれは間違ったやり方のような気がするなと…。

#2 [anime] 「歴史秘話 仮面ライダーヒストリア」を視聴

NHK-BSで放送されていた番組を録画していたので視聴。NHK-BSだったような気がする。たぶん。

ライダーシリーズの各作品を、一つにつき1〜2分ほどで紹介していくだけなのに、1時間番組になっていた…。このシリーズがどれだけ長く続いているのか、改めて認識させられた…。

それにしても、こういう番組がNHKで紹介されるようになったんだなあ…。いや、結構前から扱ってくれてる状態ではあるのか。ライダー響鬼の時も紅白歌合戦でED曲が流れたし…。

2021/10/06(水) [n年前の日記]

#1 [python][pygame] 道路の自動生成処理を書き直し

Python + Pygame を使って道路の自動生成処理っぽいことができないか試しているのだけど。

道路相当を一旦全部引いた後で、マップ全体をスキャンして、交差点や角を探して置換する方法は無理がありそうだと分かってきた。交差点その他として判別すべきパターンが、あまりにも多過ぎる…。Tiled上で、マウスでポチポチと、置換前後のパターンを増やしてみたけど…。こんなの人間が目視と手作業でリストアップなんかしてられない…。絶対にパターンの見落としもあるだろうし…。

そもそも、ロードローラーモドキのオブジェクトを大量発生させて、一気に並列して動かすから処理が面倒臭くなるような気がしてきた。一本一本、順々に引いていけば、タイルを置いていく際に交差点かどうか等の判断も比較的できるようになるのでは…。

ということで、処理の書き直しを始めた。

パターン置き換え用辞書の生成スクリプトを書いたり等もしてたけど、そのあたりは没だな…。

2021/10/07追記。 :

せっかく書いたのにもったいないから一応アップロード。

動かすと以下のような感じになる。Spaceキーで生成し直し。




ソースや使用ファイルは以下。

_05_makeroadtilemap2.py
_rep_dic0.json
_road_chip.png

辞書生成用のスクリプトや、置換パターンの Tiled用ファイルは以下。

_04_make_replace_dic.py
_road_replace_pattern.json
_road_chip.json
_road_replace_pattern.tmx

置換パターンを手作業でリストアップしていったけど、以下のような量になったわけで…。

road_replace_pattern_ss01.png

これでもまだパターンが足りない…。しかも、一度正しく置換した後、また間違った状態に置換し直している可能性も否定できないわけで…。この方法はダメだなと…。

#2 [nitijyou] 上着の黄ばみを落とそうと試みた

春や秋頃に着る上着の黄ばみがちょっと酷くなってしまったので、黄ばみを落とせないか試してみた。以下のページを参考にした。

_シャツの黄ばみ取りは何が正解か | 家事の裏ワザ | 連載 | コラム - くらしメイド | DCM
_あの白さがよみがえる!シャツの黄ばみ一発解消SP - NHK ガッテン!

ホーマックで、丹羽久 過炭酸ナトリウム 500g と、DCMブランドの台所用洗剤を購入。過炭酸ナトリウムは300〜400円だった気がする。

前述のページに書かれた手順に従って作業。過炭酸ナトリウム、台所用洗剤、水を、同量で混ぜて、使い古した歯ブラシで、服の黄ばみの酷いところにペタペタと叩きつけるように塗っていった。

その手の解説ページには、混ぜ合わせてペースト状に、と書いてあったけど、過炭酸ナトリウムの粉が全然溶けず、ポロポロとした塊になってしまって、これでいいのかなと不安になったりもして。まあ、後でお湯につけたり、スチームをあてる時に溶けだして化学反応を起こすのだろうから、塗ってる段階ではポロポロした感じでもいいのかもしれない。むしろ、この段階で無理矢理溶かそうとしてお湯を入れたりしたら、そこで化学反応が終わってしまってよろしくないのかも。

最初のページには、それぞれ同量で、と書いてあったけど、後になってから、ガッテンのページで、過炭酸ナトリウムが大さじ半分、台所用洗剤が大さじ1、水が大さじ2、と書いてあったことに気づいた。まあ、目安としてはそんな感じで、ということなのだろう…。

最初、素手で作業をしてしまったけど、途中でパッケージ裏面に「手に付いたらすぐ水で洗い流すこと」と書いてあることに気が付いて、慌てて手を水洗い。使い捨てのビニール手袋をつけて作業すべきだった…。弱アルカリ性らしいから皮膚が荒れる可能性が高いのだな…。

風呂場で、給湯器から50度ぐらいのお湯を出して、タライに満たし、上着をゆっくりと沈めた。この手のソレは50度ぐらいで効果が発揮されるそうで…。今になって考えてみると、タライよりバケツのほうが合ってたような気もする…。

浸してない部分があるとそこだけ色が変わってしまいそうなので、上着が浮き上がってこないように、洗面器を置いて重石代わりにしてみた。本来はビニールか何かで軽く蓋をしたほうが、お湯が冷めにくくなって効果が更に期待できるらしいのだけど、今回はイイ感じのブツが見当たらなかったので、洗面器のみが蓋代わり。

おそらく、2時間ぐらい浸してたのかな…。お湯が冷めたら、洗濯機でフツーに洗濯。すすぎをしっかりしないと、残った洗剤で更に黄ばみが出てしまったりするそうで。

結果としては、目視でハッキリわかるぐらいに黄ばみが落ちてくれた。こんなに落ちるのか…。スゴイな…。

2021/10/07追記。 :

スマホから写真を取り出せたので一応アップロード。ちょっと汚い画像だけど、効果のほどは分かるだろうと…。

before。
kibami_ss01.jpg

after。
kibami_ss02.jpg

before。
kibami_ss03.jpg

after。
kibami_ss04.jpg


2021/10/07(木) [n年前の日記]

#1 [python][pygame] 道路の自動生成処理の雛形がたぶんできた気がする

Python + Pygame を使って道路の自動生成処理っぽいことができないか試していたけど、最低限の処理と言うか、雛形になりそうな処理は書けたような気がする。道路の幅は一種類だし、曲がる時は直角にしか曲がらないけど…。

動作確認環境は、Windows10 x64 21H1 + Python 3.9.7 64bit + Pygame 2.0.1。

とりあえず、こんな感じに。Spaceキーで再作成できる。




単にグリッド上で1マス1マスを順に塗り潰していくだけなら、ここまで悩まなかったのだけど…。道路のタイルパターンに、横もしくは縦方向を持たせて、交差点や角では別のパターンになる、という条件でドット絵を作ってしまったものだから、面倒臭いことに…。

ソースや使用画像。 :

ソースや使用画像は以下。ソースが長くなってしまったので、ファイルを置いておくだけにしておく。CC0 / Public Domain ってことで。

_06_makeroadtilemap3.py
_road_chip.png

仕組みについてメモ。 :

一応、仕組みについて簡単にメモしておく。

タートルグラフィックスっぽく、一筆書きのような感じでグリッドを埋めていくわけだけど…。上下左右のどれかで進む方向を決めて、ランダムな回数分進んだら、乱数で方向を変えて、またランダムな回数分進んで、を繰り返して…。グリッド外に飛び出したら1本分の処理終了、みたいな。

ただ、その場所に何のタイルを置くかで悩んでしまった。上下左右をチェックして、置くべきタイルを決めるわけだけど…。

check_pos_ss01.png


以下の場合は、接続しないものとして扱えば良い、と気づくまでハマってしまった。まあ、無理矢理繋げてしまう方法もありそうだけど…。

not_connect_pat_ss01.png


逆に言うと、上記以外の場合は、接続するものとして扱う。

connect_pat_ss01.png


また、何かしらのタイルとぶつかった場合は、そこで処理を打ち切るか、それともそのまま上書きして進むかを乱数で決める。

die_or_continue_ss01.png


自分の進む方向と重複したタイルにぶつかった場合は、そこで処理を終了する。そのまま進んでも、既に存在する道路を上書きしていくだけなので…。

condition_stop_ss01.png


大体こんな感じで分かるだろうか…。

今後の課題。 :

元々は3種類ぐらいの道路幅で生成したいと考えていたので、今後は 2x2, 4x4 の道路幅で生成できないか試してみたいなと…。更に、斜めの道路も入れたい…。もっとも、斜めの道路が入ると接続部分で出現するパターンがめちゃくちゃ増えるので、斜めは無しという前提にしたほうがいいのかもしれないけど…。

道路が無い領域を検出してビルを配置する、という処理もさせたいけど、そのためには検出した領域をイイ感じの矩形に分割していく処理が必要になりそうでもあり…。そもそも歩道も置かないといけないから、領域の一番外側のグリッドを歩道タイルで埋める処理も必要になるよな…。

2021/10/08(金) [n年前の日記]

#1 [python][pygame] 別幅で道路の自動生成を試してる

2x2 のタイルで道路の自動生成ができないか試しているところ。

タイルマップの配列数を、横1/2、縦1/2にして生成すれば済むのでは、と安易に思って試してたけど、道路同士が隣り合った際の交差点の検出が今一つ…。交差点になるはずのタイルの上下左右に横断歩道に相当するタイルを上書きするのだけど、そこに上書きされると困る、てな場合も描き込まれてしまって…。2x2のタイルではなく、4x4、8x8のタイルにして、1つのタイルに対して事前に隙間を盛り込んだ状態で埋めてみたらどうだろうと試し始めたり。

斜めの道路も引きたいので、扱う方向の種類を、4方向から8方向に増やさないと…。ただ、斜めの道路の場合、タイル位置の進め方が変わった感じになるはずで…。x, y が、(+1, 0), (0, +1), (+1, 0) と進む、みたいな。テーブルを書けば対応できそうな気もしているのだけど…。

2021/10/09() [n年前の日記]

#1 [python][pygame] 別幅で道路の自動生成を試してる。その2

8x8のタイルで道路の自動生成ができないか試しているところ。

直角に曲がる処理ならそれっぽくなったけど、8x8は大き過ぎて、見た目で同じパターンばかり出現してしまう…。どうしたもんか…。まあ、斜め処理を入れてから対策を考えよう…。

2021/10/10() [n年前の日記]

#1 [anime] 「超時空要塞マクロス 愛・おぼえていますか」を視聴

BS12で放送されていたので視聴。TVアニメ「超時空要塞マクロス」の劇場版。たしか当時、劇場で見たような記憶があるような、無いような。それともTVで見たのかな。記憶が怪しい。

映像が…スゴイ…。究極の手描き商業アニメ、だろうか…。

もっとも、当時はCGなんて無かったから手で描く以外になかったわけで、今ならどれもCGで作るべき映像だよなと…。手描きでなければ描けない動きではないし…。板野サーカスは金田アクション等と違って、理屈で生み出した動きだから、後進にも伝授可能だし、CGでも再現できるのが強みのはずなわけで…。

あちこちのカットで画面がボケてるあたりが気になった。セルを何枚も重ね過ぎて、セルの厚みでボケてるのかと思ったけど、どう見てもセルをそんなに重ねてなさそうなカットでボケてたり、全部がボケずに一部だけボケたり、字幕?テロップ?が妙に太い見た目になってたりしたので、セルの重ね過ぎということではなさそう。どうしてこういう状態になってるんだろうと…。何にせよ、この作画でこの撮影状態は結構もったいないなと…。セルが残ってたらデジタルで再撮影等もできるんだろうけど、そんなのほとんど残ってないだろうし。もったいないなあ…。

一部の凄惨なカットがぼかされてたり、スタッフロールで何故かミンメイのライブ映像が出てきたので、劇場公開版というわけではなさそう。いやまあ、当時の版はもう存在してないのかもしれんけど…。

スタッフロールに、京アニの、故・木上益治さんの名前があった。ググってみたら、1991年頃に京アニ所属になったらしいので、1984年公開のこの作品への参加時は京アニ所属ではないのだろうけど…。担当カットをググってみて、またビックリ。あのシーンを描いていたのか…。やっぱり実力派アニメーターだったんだなと…。

2021/10/11(月) [n年前の日記]

#1 [python][pygame] 別幅で道路の自動生成を試してる。その3

8x8のタイルで道路の自動生成ができないか試しているところ。

斜めの道路のパターンを入れてみたらぐちゃぐちゃな生成結果になった。バグを取らないと…。あり得る組み合わせのパターンをテーブルで列挙しないとダメだろうな…。

#2 [anime] 「SWITCHインタビュー 達人達 鈴木敏夫 x 津野海太郎」の回を視聴

スタジオジブリのプロデューサー鈴木敏夫さんと、雑誌編集者・作家の津野海太郎さんの対談番組。NHK Eテレで再放送されていたので録画して視聴。2020/11/28に初回放送だったらしいけど、当時放送があることを知らなくて見れなかったので再放送はありがたい。ちなみに、「アーヤと魔女」がNHK総合で放送されてない時期の対談映像。

鈴木Pは、トトロとの火垂るの墓の企画書を出したら偉い人に怒られたという、いつもの(?)エピソードを披露。ただ、「お偉いさんは昭和30年代が大嫌い」「新潮社の本を徳間書店が映像化するのは面白いと訴えたらお偉いさんが乗り気になってトントン拍子で話が進み始めた」という裏話は聞いた記憶が無かったので興味深かった。対談相手の津野さんも、徳間書店は新潮社にコンプレックスがあるという話に同意してたあたり、出版業界内の共通認識があるのだろうなと。

「アーヤと魔女」は予算がかかり過ぎてしまったけどNHKが追加の予算を出してくれなくて困ってる、という話も気になった。TV放映した作品を何故劇場公開するのだろうと不思議だったけど、赤字になった分を少しでも補填したいということだったのかなと邪推したりもして。もしそういう理由であれば、これまでの劇場向けジブリ作品並みの結果は最初から求められてないのかも。NHKがその分を出してくれてたら、劇場公開せずに済んだかもしれない…?

津野さんの作業部屋で、「本を読むことは良いことだという認識が近年無くなってしまった」「自分達は本を読むことは良いことと無条件で思い込んでる世代」という話が出ていて、そのあたりも興味深かった。文章を読んだり、文章を書いたり(打ち込んだり)する機会は、インターネットの普及でむしろ増えた気もするけれど、twitterのような文字数制限があるサービス上での話だったりするだろうから、本を読んでいる状態と比べると、文章への付き合い方が違っている可能性もありそうだなと…。このあたり、津野さん自身が電子書籍云々について言及した書籍を10年以上前に書いていたようで、対談内ではもっと深いところまで言及していたけど映像ではカットされてたりするのかなと思ったりもして。ていうか、そこだけを取り上げて別番組が作れそうなテーマではあるよな…。

2021/10/12(火) [n年前の日記]

#1 [python][pygame] 別幅で道路の自動生成を試してる。その4

8x8のタイルで道路の自動生成ができないか試しているところ。

斜めの道路のパターンはなんとか描けるようになった。ただ、斜めの道路に別の道路が交差した時の見た目をどうするかで悩んでしまった。

一応、ドット絵側には、斜め道路と交差した時に使うタイルも用意してあるけれど、それらを使わなくても繋がってるように見せることができることに途中で気づいて、だったらその処理で済ませてしまってもいいかな、パターン数も減らせるし、と…。当初の予定より見た目がガクガクした道路になってしまうけど、そもそも斜め道路の幅が不自然なので、今更見た目の自然さにこだわっても大差は無い気もするわけで…。ただ、横断歩道の描画だけは省略できない感じがするなと。横断歩道の有無は、道路らしさを醸し出すにあたって結構重要な気がする。

中ぐらいの道路幅はそれらしく描けるようになったので、太い道路幅の処理に手を付け始めた。

中ぐらいの道路幅の1パターンを8x8タイルで作ったけれど、太い道路幅のパターンも8x8タイルで収まりそう。なので、パターン定義ファイルを差し替えるだけで太い道路幅でもそれらしい道路生成ができてしまった。

中ぐらいの幅の道路と太い幅の道路の生成ができたので、両方を重ねて描画する処理を追加したい。

2021/10/13(水) [n年前の日記]

#1 [python][pygame] 別幅で道路の自動生成を試してる。その5

8x8のタイルで道路の自動生成ができないか試しているところ。使用環境は、Windows10 x64 21H1 + Python 3.9.7 64bit + Pygame 2.0.1。

なんとかどうにかある程度は一応それらしく見えてくれるような感じになってきた気がする。まだ盛り込めてない処理が多いけど…。

ソースと使用画像その他。 :

ソースと使用画像その他も一応アップロード。CC0 / Public Domain ってことで。

_make_road_ml.py
_road_chip.png
_block_road_middle.json
_block_road_large.json

同じフォルダに入れて、python make_road_ml.py で実行できる。

以下のキー操作を受け付ける。
  • SPACEキー: 道路を作り直し。
  • Gキー : グリッド表示。
  • Sキー : 生成した道路をpng画像として保存。
  • カーソルキー or WASDキー : スクロール。(生成画像がウインドウより大きい場合)
  • Qキー, ESCキー : 終了

パターン定義ファイルの生成。 :

今回、8x8タイルで1パターンとして扱って処理をしてみたけれど、パターンの作成にはマップエディタ Tiled を利用させてもらった。

_Tiled | Flexible level editor

Tiled用のファイルは以下。

_road_large.tmx
_road_middle_new.tmx
_road_chip.tsx
_road_chip.json
_road_chip.png

今回は、以下のような見た目のパターンを作った。

road_middle_new.png

road_large.png


番号を描き込んでみると以下のような感じ。

road_middle_new_ss01_fix.png


Tiled から .json でエクスポートして、Python + Pygame で利用できるように変換したい。エクスポートした .json は以下。

_road_large.json
_road_middle_new.json

この2つの .json を Pythonスクリプトで読み込んで、パターン定義ファイルとして利用できる .json に変換する。変換用 Pythonスクリプトは以下。処理内容は、1次元配列を2次元配列にしているだけ…。

_make_road_pat_json.py

python make_road_pat_json.py を実行すると、以下の2つのファイルを生成・保存する。

_block_road_middle.json
_block_road_large.json

それぞれ、パターン定義ファイルとして利用できるかどうか動作確認するための Pythonスクリプトも書いた。

_test_draw_blocks.py

python test_draw_blocks.py を実行すると、block_road_large.json を読み込んで、ウインドウに表示する。スクリプト内のファイル名指定を書き換えれば、block_road_middle.json も読み込める。

課題。 :

生成結果をよく見ると、中幅道路と太幅道路の、交差部分の見た目がおかしいわけで…。道路脇の(路肩|路側帯)もドット絵に含ませているものだから、交差部分にもソレが見えてしまう。本来なら、そこだけ(路肩|路側帯)が消えているタイルを置き直さないといけない。

また、太幅道路に、中幅道路が繋がっている場合は、中幅道路側に横断歩道を描画したい。そういう箇所には横断歩道があるはずだろうと。

さらに、斜めの太幅道路に中幅道路が繋がっている場合は、ちゃんと隙間を埋めるような見た目になるタイルを置きたい。

つまるところ、以下のようなタイルの置き換えが必要になりそうなのだけど…。

road_large_overlap_ss01.png

この手の組み合わせが、これだけで済むとは思えないわけで…。また、この後、細い幅の道路も追加したいと思っているので、そうなると組み合わせ数が更に膨大になる…。

そもそも、道路1マス分に(路肩|路側帯)まで含めたドット絵を描いてしまったあたりがマズかったのではないかと思えてきた。道路の周辺に歩道相当のタイルを配置して、(路肩|路側帯)はそのタイルに含めたほうが処理が楽になったのではないか…。ちょっとドットを打ち直して考え直してみたい…。今の方法のままでは、どうも終わりが見えないし…。

#2 [python] Python + PIL で画像を分割したり比較したりしてみたり

Python + PIL (Pillow) を使って、画像を分割したり、分割した画像群を比較してユニークな画像を抜き出したりする処理を試してみた。環境は、Windows10 x64 21H1 + Python 3.9.7 64bit + Pillow 8.3.2。

画像を分割する処理は、以下のページが参考になった。ありがたや。

_[Python3.6]画像を任意の枚数に分割する - Qiita

.crop(x, y, x + w, y + h) を使えばいいらしい。

画像群の比較は、NumPy とやらを使うと楽にできそうと知った。

_Python, NumPyで画像処理(読み込み、演算、保存) | note.nkmk.me
_numpy - 配列同士を比較する関数について - pystyle

im = numpy.array(Image.open('hoge.png')) で、ndarray なる配列(?)が得られるらしい。また、pil_img = Image.fromarray(im) で、PIL の画像形式に変換できて、pil_img.save("fuga.png") で保存できる模様。

ndarray 同士の比較は、numpy.array_equal(a1, a2) が使えそうだなと…。これで、寸分たがわず同じ画像かどうかを判定することができるので、リストに登録した画像群と比較して、同じ画像だったら除去、同じ画像ではなければリストに追加、という処理をして、ユニークな画像群だけを得ることができた。

できたスクリプトは以下のような感じ。大きいサイズ(今回は1024x768ドット)の画像群を読み込んで、64x64ドット単位で分割して、ユニークな画像だけを抜き出して、64x64ドットの画像群として保存する、という処理をしている。

_10_split_pattern.py
import glob
from PIL import Image, ImageFilter
import numpy

infiles = "../output_images/*.png"
bw, bh = 64, 64

def main():
    l = glob.glob(infiles)

    imgs = []
    for s in l:
        im = Image.open(s)
        iw, ih = im.size
        print("%s, w x h = %d x %d" % (s, iw, ih))

        for y in range(0, ih, bh):
            for x in range(0, iw, bw):
                c = im.crop((x, y, x + bw, y + bh))
                n = numpy.array(c)
                imgs.append(n)

    nimgs = []
    for n in imgs:
        for o in nimgs:
            if numpy.array_equal(n, o):
                break
        else:
            nimgs.append(n)

    cnt = 0
    for n in nimgs:
        fn = "pat_%06d.png" % cnt
        im = Image.fromarray(n)
        im.save(fn)
        cnt += 1


if __name__ == '__main__':
    main()

2021/10/14(木) [n年前の日記]

#1 [nitijyou] 親父さんが入院

詳細はGRPでメモ。

2021/10/15(金) [n年前の日記]

#1 [windows] 共有プリンタで印刷できない問題について調べてた

某所からメールでPC相談。昨日今日になって、突然LAN内の共有プリンタから印刷できなくなったとの話。

以前も似たような相談があって、その際の原因は Windows Update だったのだけど…。プリンタ関係のセキュリティの設定が変更されてしまって、脆弱性対策済みの状態にすると印刷できなくなる、という不具合で…。その際は、レジストリを修正してとりあえず印刷できるようにはしたのだけど…。

また Windows Update 絡みかなとググってみたけど、それらしい不具合報告は見つからず。ただ、今現在、また違う感じのプリンタ関係の不具合が発生しているようでもあり…。

_Windows10 / Windows11でプリンターに関する複数の不具合。Windows10はKB5006670等で一部修正 | ニッチなPCゲーマーの環境構築Z
_「Windows 11」に新たなプリンター問題が3件 〜既知の問題は計6件に - 窓の杜

某所のPCは Windows8.1 だった気がするけど、上記の不具合は Windows8.1でも起きているようで。ただ、特定の接続方式で発生する、という話もあって…。具体的にはどういう接続なのか、解説が無い…。

Microsoft Edge 上から印刷しようとしたら印刷できなかった、とも聞いたので、他のブラウザで試してみてほしいと連絡したところ、Google Chrome でも印刷できなかったと報告が。すると Edge だけの不具合ではないな…。OSレベルで共有プリンタが使えない状態なのだろう…。

2021/10/16() [n年前の日記]

#1 [windows] 共有プリンタから印刷できないのはWindows Updateのせいだった

某所から、共有プリンタから印刷できなくなったというトラブル相談を受けたのでお邪魔してきた。小雨の降る中、雨合羽を着て電動自転車で某所まで。AM09:00-AM11:30まで作業。

構成としては、Windows8.1機に EPSON PX-M6711FT という複合機がUSB接続されていて、その PX-M6711FT を共有プリンタとして設定。LAN内の他のWindows8.1機から利用できるようにしてあった。 *1

結論を先に書くと、印刷できなくなった原因は Windows Update だった。

2021/10/13前後に配信された KB5006714 (2021-10 x64ベースシステム用 Windows8.1向けセキュリティ マンスリー品質ロールアップ) をインストールすると、共有プリンタから印刷できなくなる。アンインストールしたらすんなり印刷できてしまった。ちなみに、アンインストールには30分以上かかる。

これと同じ症状は2021/09の Windows Update でも起きていたのだけど、その際はレジストリを修正して以前の動作にすることで ―― 脆弱性対策をしてない状態にすることで、どうにか印刷できるようにしていた。

_KB5005565に印刷ができなくなる不具合。対処方法あり [Update 2: 脆弱性に影響しない恒久的解決策判明] | ニッチなPCゲーマーの環境構築Z
【キー】HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Print
【DWORD】RpcAuthnLevelPrivacyEnabled
【値】『1』で脆弱性対策有効、『0』で脆弱性対策無効

KB5005565に印刷ができなくなる不具合。対処方法あり [Update 2: 脆弱性に影響しない恒久的解決策判明] | ニッチなPCゲーマーの環境構築Z より


ただ、今回の Windows Update で、そのレジストリ修正の効果も無くなってしまった模様。

今後の選択肢。 :

某所の方と今後取れそうな策について話し合ったのだけど、以下の3つぐらいしか策が思いつかず…。
  • A. Microsoftが修正してくれるまで、Windows Update をずっとインストールしない状態でPC群を使い続ける。
  • B. LAN接続できるプリンタ or 複合機を新規に購入する。PCと複合機をUSB接続して共有プリンタとして利用しようとするから問題が起きるわけで、複合機を直接LANに参加させてしまえば問題を回避できる可能性がありそう。
  • C. 印刷したい時は一旦PDF出力して、プリンタが繋がってるPCからPDFを開いて印刷する。

しかし、どれも問題があるわけで…。
  • Aは、セキュリティホールが放置されてしまう。けれど、印刷できなければそもそも仕事にならない…。
  • Bは、新規購入になるからお金がかかる。
  • Cは、どう考えても面倒臭い。

Microsoftはこの不具合を修正するつもりがあるのだろうか…。ずっとこのままだとしたら、どうすれば…。

やはり不具合が起きるらしい。 :


*1: ちなみに、EPSON PX-M6711FT は有線LAN、もしくは無線LAN接続もできるけど…。LAN接続は別のLANで利用されていて、Windows8.1機で構成されたLAN側ではUSBで接続して利用するしかない状態。

2021/10/17() [n年前の日記]

#1 [gimp] GIMP 2.10.28 をインストールした

今まで Windows10上で GIMP 2.10.22 x64 Portable samj版を使っていたけど、GIMP 2.10.28 x64 Portable samj版をインストールしてそちらを使うようにしてみた。

今までと同じ設定に再設定していく作業が面倒臭い…。特定ファイルをコピーするだけで反映できたらいいのに…。もっとも、設定を保存しているファイルが分かっても、おそらく記録された各フォルダのパス指定も変更しないと問題が起きそうな予感もあり…。

矢印生成スクリプトが動かないことに気づいた。 :

GIMPのバージョンを上げたついでにアレコレ動作確認をしていたら、矢印生成スクリプト、sg-arrow-stroke-path.scm が正常に動作しないことに気づいた。

_矢印ストロークパス

パスを生成して、先端からハンドルを引き出して矢印の角度相当を指定して、編集 → 矢印ストロークパス、で呼び出すと、レイヤー全体が前景色で塗り潰されてしまう。

以前から動作しなかったのだろうかと気になって、GIMP 2.8.22 Portable 上で動作確認してみたけれど、そちらならそれっぽく動作した。ということは、GIMP 2.10 になった際に Script-Fu の仕様が変わって動かなくなっていたのだろうか。いや、Script-Fu というより、GIMPのAPI?が変わったのだろうけど。

ちなみに、arrow-set-size.scm という矢印生成スクリプトは動いてくれた。

_Arrow Script
_ぼやけのない自由な形の矢印を挿入するスクリプト ?GIMP | カンデザWeb

こちらのスクリプトで生成した矢印は、先が丸まっていて、あまり好みではないのだけど…。

#2 [digital] 階下のREGZAが不調

茶の間で使っている REGZA 37Z9000 の画面がおかしいとお袋さんから報告。見てみたところ、画面の上半分に横線が表示されて、映像が時々フリーズする感じで。音声はちゃんと聞こえる。

B-CASカードを抜き差ししてみたり、本体の電源ボタンを長押ししてリセットをかけてみたけれど、変化なし。

ググってみたところ、東芝 REGZA Z9000シリーズでは結構発生している不具合だそうで…。

_価格.com - 『画面に横線が入るようになりました』 東芝 REGZA 37Z9000 [37インチ] のクチコミ掲示板

部屋の温度が7度以下になると発生するとか、8時間以上電源を入れてないと発生する、といった傾向があるらしい。液晶パネルを制御してる基板の不良だそうで…。そのまま電源を入れて本体が温まると症状が出なくなる時もある、とかなんとか。

もう買い替えの時期だろうか。しかし、買い替えとなると、REGZAにUSB接続している外付けHDDに今まで録画してきた番組が全部見れなくなるはずで…。この手のTVで録画した番組は、その製品個体でしか再生できないように暗号化された状態で保存されているわけで…。せめて、同じ会社の製品に買い替えた時ぐらいは、今まで使ってた製品の録画データを移行可能、ぐらいの状況を実現しておいてほしかった。最低限そのくらいはできなきゃあかんやろと…。日本の家電メーカは、本当にろくでもないクソ仕様を堂々と普及させてしまったもんだよなと…。こういう仕様では迂闊に買い替えもできないじゃん…。

一応、今まで使ってたTVがまだ生きているなら、録画番組をDTCP-IP対応のNASにダビングして、以降はそのNASにアクセスして番組を再生、という形で引っ越しができなくもないらしいけど…。今現在販売されてるTVで、NASにアクセスして録画番組再生可能な製品がどれだけあるのかがよく分からず…。価格.comで検索してみたけど、各製品が実際どこまで対応しているのか、今一つ分からんなと…。例えば、LAN経由のダビングができるかどうか、NASに入った録画番組を削除できるのか等々、各製品の公式サイトを眺めてすぐに分かるかと言えばそうでもなく…。

2021/10/18(月) [n年前の日記]

#1 [gimp] GIMPのブラシファイルを作ってる

Windows10 x64 21H1 + GIMP 2.10.28 x64 Portable samj版上で、GIMPの矢印ブラシファイルを作成中。

今まで色々な矢印ブラシファイルを追加してきて、結果、ファイル数が多くなってしまったので少し整理していたのだけど。

_GIMP Arrow Brush set by Banekai on DeviantArt
_arrow brushes color 1
_arrow brushes color 2
_arrow brushes BW 1
_arrow brushes BW 2
_arrow brushes black gloss
_hand pointer brushes
_button arrow brushes
_gimphelp.org Arrow Action
_cursor brushes

それぞれのブラシについて改めて確認してみたら…。 これじゃ使い辛い…。

GIMP って昔からある画像編集ソフトだから、当時は何かにつけてファイルサイズが小さいほうが良しとされていたようで、故に、昔から配布されているブラシ画像も妙に小さいサイズになってる傾向があって…。また、どうも当時はブラシファイル(.gbr)のフォーマットに制限があったか、あるいは仕様についてよく知られてなかったのか、描画色を反映せず、ブラシ画像に含まれている色でしか描画できないタイプのブラシも多く…。

ということで、この際自作してしまおうかなと。せめて 512x512ぐらいの画像サイズにしたい。てな感じで作業を始めたところ。

2021/10/19(火) [n年前の日記]

#1 [gimp] GIMP用の矢印ブラシを作ってみた

GIMP 2.10上で利用できる矢印ブラシを作ってみた。環境はWindows10 x64 21H1 + GIMP 2.10.28 x64 Portable samj版。

形状に関して参考にした矢印ブラシ群は以下。

_GIMP Arrow Brush set by Banekai on DeviantArt
_arrow brushes BW 2

どれもブラシ画像が小さ目なのでブラシサイズを大きくするとぼやけてしまうこと、また、描画色が反映されずに必ず黒一色で描画されてしまうことが気になっていたわけで。

そんなわけで、大き目のブラシ画像(512 x 512ドット)を作成し直して、かつ、描画色が反映されるように、グレースケール画像としてGIMP用ブラシファイル(.gbr)を保存(エクスポート)してみた。

尚、前述のブラシ群の中から、自分が利用しそうな形状のブラシだけを自作した。

種類の一覧は以下。

m256_arrow_01_14_sample.png

ファイルは以下。

_arrow_m256_20211019.zip

GIMP用のブラシファイル、.gbr の他に、.svg と .png も同梱しておいた。
ライセンスは…。arrow brushes BW 2 は Public Domain らしいので、今回作成したブラシもそれと同様に Public Domain ってことで。GIMP Arrow Brush set by Banekai はライセンスが不明だけど、「自由に使ってくれ」「使ったら報告が欲しいけど別に報告しなくてもいいよ」と書いてあるように見えるので、今回作成したブラシもソレに従って、自由に使ってくれ、ってことで。

「右向きしかないんだけど?」「大き過ぎるんだけど?」 :

Q. 「コレ、右向き矢印しかないんだけど? 左、下、上は?」
Q. 「コレ、ブラシとして大き過ぎるんだけど?」

A. GIMP 2.10 はブラシのオプションに「角度」という項目があるので、角度に、90度、180度、-90度、等を指定すれば、下、左、上向きになります。また、「サイズ」という項目もあるので、好きなサイズを指定すれば小さいブラシとして使えます。と一応メモ。

ss_20211019_195421.png

余談。テキストツールを使ったほうが早い。 :

余談。GIMPには矢印を描画する機能が無いので、矢印ブラシを新規追加しようだの、矢印描画スクリプトを新規導入しようだの、そういうアレな話になるけれど。

日本語環境でGIMPを使ってるユーザなら、テキストツールを使えば矢印を簡単に描画できますよ、と一応メモしておくのです。

_Gimp: 手っ取り早くシンプルな矢印を描く方法 | anobota

日本語フォントを選べば、「みぎ」「ひだり」「うえ」「した」「やじるし」で矢印記号を打ち込めるので…。
  • テキストだからサイズを大きくしても画像が荒れない。
  • テキストレイヤーからパスを生成すれば回転拡大縮小も自由自在。画像も荒れない。
  • 標準機能で使える。
矢印の形状にこだわらないなら、かなりオススメです。

余談。水平反転や垂直反転。 :

余談。GIMPのブラシのオプションには「角度」という項目があるので、任意の向きに回転させれば事足りる、そんな形状のブラシであれば、全方向分を持たずに、一方向分だけのブラシを持っておくだけで済むのだけど。

場合によっては、ブラシ形状を水平反転、垂直反転して使いたい時もあるわけで…。でも、GIMP のブラシオプションに、「xx反転」なる項目は無いわけで…。

そういう時はどうすればいいのか、少しググってみたのだけど、どうやらクリップボードブラシを利用することでなんとかなりそうだと分かったので一応手順をメモ。

まずは、ブラシを画像として開く。ブラシを選択 → 右クリック → 画像として開く、を選ぶ。

gimp_brush_flip_ss01.png


ブラシ画像が開かれた。

gimp_brush_flip_ss02.png


画像を変形させる。画像 → 変形 → 水平反転 or 垂直反転 or etc.

gimp_brush_flip_ss03.png


変形させた画像をクリップボードにコピーする。Ctrl + A。もしくは、選択 → すべて選択。

gimp_brush_flip_ss04.png


コピーする。Ctrl + C。もしくは、編集 → コピー。

gimp_brush_flip_ss05.png


これで、クリップボードに、変形したブラシ画像がコピーされた状態になった。

ブラシ一覧ウインドウの一番左上に、「Clipboard Image」という名前のブラシがあるはずなので選択。これが、クリップボードに入っている画像をブラシ画像として利用できるGIMPの機能、とでもいうか…。

gimp_brush_flip_ss06.png


ということで、元のブラシ画像を水平反転した状態でブラシ描画ができた。

gimp_brush_flip_ss07.png


手順が多くて面倒臭いけど、それでも一応、一つのブラシを水平反転や垂直反転して使うことができると分かった。

でもまあ、利用頻度が多いなら、その画像を .gbr としてエクスポートして、新規ブラシとして追加したほうがいいですわな…。

ていうか、どうして GIMP のブラシには水平/垂直反転が無いんだろう…。もっとも、反転した状態からサイズ変更や回転をさせると、ブラシ描画の処理内容が更に面倒なことになりそうではあるか…。

#2 [nitijyou] 日記をアップロード

2021/09/22を最後に日記をアップロードしてなかったのでアップロード。

以上、19 日分です。

過去ログ表示

Prev - 2021/10 -
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project