2020年12月13日日曜日

Python+Pillowでミニチュア風に上下をぼかす

最近、お出かけすることが減って、Pythonを勉強しています。
そのPython言語の、Pillowという画像ライブラリを使ったスクリプトです。
Pythonをインストールして、Pillowのライブラリをpipでインストールしておく必要があります。
記事を書いている時点のPythonは3.8です。

前回のToycamera風に加工するスクリプトは、黒あるいは白で塗りつぶした画像を
丸いマスクでブレンドしていましたが、今回はぼかした画像を
横長な長方形のマスクでブレンドしています。
今回のスクリプトは、おもちゃっぽくするために、ブレンドした後の画像の彩度を上げて、
メディアンフィルターで質感を変えています。

以下にスクリプトのコードを書きます。


"""
ミニチュア風に上下をぼかす
tkinterを使ったGUI版
Usage : コマンドラインから以下のコマンドで起動
    python miniture_gui.py
"""

import os
from PIL import Image, ImageDraw, ImageFilter, ImageTk, ImageEnhance
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog, messagebox

class FormClass:
    """ 
    ミニチュア風に加工する画面のフォームを作成するクラス
    """

    def __init__(self, root):
        # インスタンス変数に初期値設定
        self.root = root     # Windowオブジェクト
        self.filepath = ""   # 入力ファイル名
        self.readimg = None  # 入力画像
        self.dst_img = None  # 加工結果画像

        rowno = 0            # 表示位置(行番号)

        # ラベルを作成
        tk.Label(root, text='入力ファイルPATH'
                ).grid(column=0, row=rowno)

        # 入力ファイル名
        self.src_path = tk.StringVar()

        # テキストボックスを作成
        tb_widget = tk.Entry(root, 
                             width=120, 
                             textvariable=self.src_path)
        tb_widget.grid(column=1, row=rowno)

        # 入力ファイル選択ボタンを作成
        btn_widget = tk.Button(root, 
                               text='入力ファイル選択', 
                               command=self.select_file)
        btn_widget.grid(column=2, row=rowno)
        rowno += 1

        # 上位置 スケールの作成
        tk.Label(root, text='上位置(%)'
                ).grid(column=0, row=rowno)

        self.upper = tk.DoubleVar()
        upper_sc = tk.Scale(
                     root,
                     variable=self.upper,
                     orient=tk.HORIZONTAL,
                     from_=0.0,
                     to=100,
                     command=self.draw_effect)
        upper_sc.grid(column=1, 
                     row=rowno, 
                     sticky=(tk.N, tk.E, tk.S, tk.W))
        self.upper.set(40)
        rowno += 1

        # 下位置 スケールの作成
        tk.Label(root, text='下位置(%)'
                ).grid(column=0, row=rowno)

        self.lower = tk.DoubleVar()
        lower_sc = tk.Scale(
                     root,
                     variable=self.lower,
                     orient=tk.HORIZONTAL,
                     from_=0,
                     to=100.0,
                     command=self.draw_effect)
        lower_sc.grid(column=1, 
                     row=rowno, 
                     sticky=(tk.N, tk.E, tk.S, tk.W))
        self.lower.set(70)
        rowno += 1

        # 境界ぼかし スケールの作成
        tk.Label(root, text='境界ぼかし'
                ).grid(column=0, row=rowno)

        self.blur_radius = tk.IntVar()
        blur_sc = tk.Scale(
                     root,
                     variable=self.blur_radius,
                     orient=tk.HORIZONTAL,
                     from_=0,
                     to=100,
                     command=self.draw_effect)
        blur_sc.grid(column=1, 
                     row=rowno, 
                     sticky=(tk.N, tk.E, tk.S, tk.W))
        self.blur_radius.set(35)
        rowno += 1

        # 効果の強さ スケールの作成
        tk.Label(root, text='効果の強さ'
                ).grid(column=0, row=rowno)

        self.strength = tk.IntVar()
        strength_sc = tk.Scale(
                     root,
                     variable=self.strength,
                     orient=tk.HORIZONTAL,
                     from_=0,
                     to=50,
                     command=self.draw_effect)
        strength_sc.grid(column=1, 
                         row=rowno, 
                         sticky=(tk.N, tk.E, tk.S, tk.W))
        self.strength.set(10)
        rowno += 1

        # ファイル保存ボタンを作成
        savebtn_widget = tk.Button(root, 
                                   text='ファイル保存', 
                                   command=self.show_save_dialog)
        savebtn_widget.grid(column=0, row=rowno,
                            sticky=(tk.N))

        self.CANVAS_WIDTH = 800
        self.CANVAS_HEIGHT = 600

        # 画像を表示するためのキャンバスの作成
        self.canvas = tk.Canvas(self.root, 
                                width=self.CANVAS_WIDTH, 
                                height=self.CANVAS_HEIGHT)
        self.canvas.grid(column=1, row=rowno, columnspan=2)


    # 入力ファイル選択ボタン押下イベント
    def select_file(self):
        # ファイル選択ダイアログを表示
        ftypes = [("All Files", ".*"),
                  ("JPEG Image Files", ".jpg .jpeg"),
                  ("PNG Image Files", ".png")]

        if len(self.filepath) == 0:
            idir = os.path.abspath(os.path.dirname(__file__))
        else:
            idir = os.path.dirname(self.filepath)
        self.filepath = filedialog.askopenfilename(filetypes = ftypes,
                                                   initialdir = idir)
        if len(self.filepath) == 0 :
            return
        self.src_path.set(self.filepath)

        # 画像を読み取り
        self.readimg = Image.open(self.filepath)

        # 加工した画像を表示
        self.draw_effect()

    # 加工した画像を表示する
    def draw_effect(self,val=0):
        if self.readimg is None :
            return

        # 円を描画する開始位置、終了位置を計算する
        w,h = self.readimg.size
        upper = h * self.upper.get() / 100.0
        lower = h * self.lower.get() / 100.0
        h_start = int(min(upper,lower))
        h_end = int(max(upper,lower))

        # マスク画像を描画する
        mask = Image.new("L", (w, h), 0)
        draw = ImageDraw.Draw(mask)

        draw.rectangle((0, h_start, w, h_end), fill=255)
        mask_blur = mask.filter(
                        ImageFilter.GaussianBlur(
                            self.blur_radius.get()))

        # ぼかし画像を作成する
        blur_img = self.readimg.filter(ImageFilter.GaussianBlur(self.strength.get()))

        # 元の画像と、塗りつぶし画像を合成する
        self.dst_img = Image.composite(self.readimg, blur_img, mask_blur)

        # 合成した画像の彩度を上げる
        img_enhancer = ImageEnhance.Color(self.dst_img)
        self.dst_img = img_enhancer.enhance(1.5)

        # medianフィルタを適用する
        self.dst_img = self.dst_img.filter(ImageFilter.MedianFilter(3))

        # 画像の表示倍率を計算する
        rate = min(1.0, 
                   self.CANVAS_WIDTH / self.readimg.width, 
                   self.CANVAS_HEIGHT / self.readimg.height)

        # 表示用に画像を縮小する
        new_w = int(self.readimg.width * rate)
        new_h = int(self.readimg.height * rate)
        small_resized = self.dst_img.resize((new_w, new_h))

        # キャンバスに画像を表示する。
        self.im = ImageTk.PhotoImage(image=small_resized)
        self.canvas.create_image(0, 0, anchor=tk.NW, image=self.im)

    # ファイル保存ボタンイベント
    def show_save_dialog(self):
        if self.dst_img is not None :
            ftypes = [("All Files", ".*"),
                      ("JPEG Image Files", ".jpg .jpeg"),
                      ("PNG Image Files", ".png")]
            ini_fname = os.path.basename(self.filepath)
            filename = filedialog.asksaveasfilename(filetypes=ftypes,
                                                    initialfile=ini_fname)
            if filename:
                # 保存先ファイルが指定されたら、加工した画像を保存
                self.dst_img.save(filename, quality=100)
        else :
            tk.messagebox.showerror(title="エラー", 
                                    message="入力ファイルを指定してください")

# windowを描画
window = tk.Tk()
# windowサイズを変更
window.geometry("1000x800")
# windowタイトルを設定
window.title("Miniture effect")

# フォームを作成、表示
FormClass(window)

# 画面を操作されるのを待つ
window.mainloop()

上のスクリプトをUTF-8のエンコーディングで、miniture_gui.py というファイルに保存します。
Windowsだとコマンドプロンプト等を開いて、スクリプトを保存したフォルダにcdコマンドで移動して、

python miniture_gui.py

で実行します。 実行すると、


このような画面を表示します。 入力ファイル選択ボタンで、ファイル選択ダイアログを開きます。 そこでファイルを選択すると、

このように画像のプレビューを表示します。 「上位置」を大きくすると、上側のぼける面積が広くなります。 「下位置」を大きくすると、下側のぼける面積が狭くなります。 「境界ぼかし」を大きくすると、ぼける領域とぼけない領域の境がわかりにくくなります。 「ファイル保存ボタン」をクリックすると、保存先選択ダイアログを開きます。 以下、このスクリプトで加工した画像をアップします。

江の島にて

羽村堰の玉川上水

福生の公園

2020年12月6日日曜日

Python+Pillowでトイカメラ風に周辺光量落ちさせる その2

最近、お出かけすることが減って、Pythonを勉強しています。
そのPython言語の、Pillowという画像ライブラリを使ったスクリプトです。
Pythonをインストールして、Pillowのライブラリをpipでインストールしておく必要があります。
記事を書いている時点のPythonは3.8です。

前回のトイカメラ風に加工するスクリプトを、TkinterというGUIライブラリを使って、
画面で操作できるようにしました。
GUI化することで、効果を確認しながらパラメータを決められるのが良いですが、
何枚も同じ加工を連続して行うのは向きません。

以下にスクリプトのコードを書きます。



"""
トイカメラ風に周辺減光させる 
tkinterを使ったGUI版
Usage : コマンドラインから以下のコマンドで起動
    python toycamera_gui.py
"""

import os
from PIL import Image, ImageDraw, ImageFilter, ImageTk
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog, messagebox

class FormClass:
    """ 
    Toycamera風に加工する画面のフォームを作成するクラス
    """

    def __init__(self, root):
        # インスタンス変数に初期値設定
        self.root = root     # Windowオブジェクト
        self.readimg = None  # 入力画像
        self.dst_img = None  # 加工結果画像

        rowno = 0            # 表示位置(行番号)

        # ラベルを作成
        tk.Label(root, text='入力ファイルPATH'
                ).grid(column=0, row=rowno)

        # 入力ファイル名
        self.src_path = tk.StringVar()

        # テキストボックスを作成
        tb_widget = tk.Entry(root, 
                             width=120, 
                             textvariable=self.src_path)
        tb_widget.grid(column=1, row=rowno)

        # 入力ファイル選択ボタンを作成
        btn_widget = tk.Button(root, 
                               text='入力ファイル選択', 
                               command=self.select_file)
        btn_widget.grid(column=2, row=rowno)
        rowno += 1

        # 塗り残す範囲の比率 スケールの作成
        tk.Label(root, text='塗り残す範囲の比率(%)'
                ).grid(column=0, row=rowno)

        self.rate = tk.DoubleVar()
        rate_sc = tk.Scale(
                     root,
                     variable=self.rate,
                     orient=tk.HORIZONTAL,
                     from_=0.0,
                     to=100,
                     command=self.draw_effect)
        rate_sc.grid(column=1, 
                     row=rowno, 
                     sticky=(tk.N, tk.E, tk.S, tk.W))
        self.rate.set(40)
        rowno += 1

        # ぼかし半径 スケールの作成
        tk.Label(root, text='ぼかし半径'
                ).grid(column=0, row=rowno)

        self.blur_radius = tk.IntVar()
        blur_sc = tk.Scale(
                     root,
                     variable=self.blur_radius,
                     orient=tk.HORIZONTAL,
                     from_=0,
                     to=40.0,
                     command=self.draw_effect)
        blur_sc.grid(column=1, 
                     row=rowno, 
                     sticky=(tk.N, tk.E, tk.S, tk.W))
        self.blur_radius.set(20)
        rowno += 1

        # 効果の強さ スケールの作成
        tk.Label(root, text='効果の強さ'
                ).grid(column=0, row=rowno)

        self.strength = tk.IntVar()
        strength_sc = tk.Scale(
                     root,
                     variable=self.strength,
                     orient=tk.HORIZONTAL,
                     from_=0,
                     to=255,
                     command=self.draw_effect)
        strength_sc.grid(column=1, 
                         row=rowno, 
                         sticky=(tk.N, tk.E, tk.S, tk.W))
        self.strength.set(80)
        rowno += 1

        # 塗りつぶし色 コンボボックスの作成
        tk.Label(root, text='塗りつぶし色'
                ).grid(column=0, row=rowno)

        self.select_color = tk.StringVar()
        color_combo = ttk.Combobox(
                     root,
                     textvariable=self.select_color)
        color_combo.grid(column=1, 
                         row=rowno, 
                         sticky=(tk.N, tk.W))
        color_combo['values'] = ('白', '黒')
        color_combo.current(1)
        color_combo.bind("<>", self.draw_effect)
        rowno += 1

        # ファイル保存ボタンを作成
        savebtn_widget = tk.Button(root, 
                                   text='ファイル保存', 
                                   command=self.show_save_dialog)
        savebtn_widget.grid(column=0, row=rowno,
                            sticky=(tk.N))

        self.CANVAS_WIDTH = 800
        self.CANVAS_HEIGHT = 600

        # 画像を表示するためのキャンバスの作成
        self.canvas = tk.Canvas(self.root, 
                                width=self.CANVAS_WIDTH, 
                                height=self.CANVAS_HEIGHT)
        self.canvas.grid(column=1, row=rowno, columnspan=2)

    # 入力ファイル選択ボタン押下イベント
    def select_file(self):
        # ファイル選択ダイアログを表示
        ftypes = [("All Files", ".*"),
                  ("JPEG Image Files", ".jpg .jpeg"),
                  ("PNG Image Files", ".png")]

        filepath = self.src_path.get()
        if len(filepath) == 0:
            idir = os.path.abspath(os.path.dirname(__file__))
        else:
            idir = os.path.dirname(filepath)
        filepath = filedialog.askopenfilename(filetypes = ftypes,
                                              initialdir = idir)
        if len(filepath) == 0 :
            return
        self.src_path.set(filepath)

        # 画像を読み取り
        self.readimg = Image.open(filepath)

        # 加工した画像を表示
        self.draw_effect()

    # 加工した画像を表示する
    def draw_effect(self,val=0):
        if self.readimg is None :
            return

        # 塗りつぶし色
        fill_color = None
        if self.select_color.get() == '白' :
            fill_color = (255, 255, 255)
        else :
            # 黒く塗りつぶす場合
            fill_color = (0, 0, 0)

        # 円を描画する開始位置、終了位置を計算する
        w,h = self.readimg.size
        radius = max(w,h) * self.rate.get() / 100.0
        w_start = (w / 2) - radius
        w_end = (w / 2) + radius
        h_start = (h / 2) - radius
        h_end = (h / 2) + radius

        # マスク画像を描画する
        mask = Image.new("L", (w, h), 255-self.strength.get())
        draw = ImageDraw.Draw(mask)
        draw.ellipse((w_start, h_start, w_end, h_end), fill=255)
        mask_blur = mask.filter(
                        ImageFilter.GaussianBlur(
                            self.blur_radius.get()))

        # 塗りつぶし画像を作成する
        plane = Image.new("RGB", (w, h), fill_color)

        # 元の画像と、塗りつぶし画像を合成する
        self.dst_img = Image.composite(self.readimg, plane, mask_blur)

        # 画像の表示倍率を計算する
        rate = min(1.0, 
                   self.CANVAS_WIDTH / self.readimg.width, 
                   self.CANVAS_HEIGHT / self.readimg.height)

        # 表示用に画像を縮小する
        new_w = int(self.readimg.width * rate)
        new_h = int(self.readimg.height * rate)
        small_resized = self.dst_img.resize((new_w, new_h))

        # キャンバスに画像を表示する。
        self.im = ImageTk.PhotoImage(image=small_resized)
        self.canvas.create_image(0, 0, anchor=tk.NW, image=self.im)

    # ファイル保存ボタンイベント
    def show_save_dialog(self):
        if self.dst_img is not None :
            ftypes = [("All Files", ".*"),
                      ("JPEG Image Files", ".jpg .jpeg"),
                      ("PNG Image Files", ".png")]

            ini_fname = os.path.basename(self.src_path.get())
            filename = filedialog.asksaveasfilename(filetypes=ftypes,
                                                    initialfile=ini_fname)
            if filename:
                # 保存先ファイルが指定されたら、加工した画像を保存
                self.dst_img.save(filename, quality=100)
        else :
            tk.messagebox.showerror(title="エラー", 
                                    message="入力ファイルを指定してください")

# windowを描画
window = tk.Tk()
# windowサイズを変更
window.geometry("1000x800")
# windowタイトルを設定
window.title("Toycamera effect")

# フォームを作成、表示
FormClass(window)

# 画面を操作されるのを待つ
window.mainloop()


上のスクリプトをUTF-8のエンコーディングで、toycamera_gui.py というファイルに保存します。
Windowsだとコマンドプロンプト等を開いて、スクリプトを保存したフォルダにcdコマンドで移動して、

python toycamera_gui.py

で実行します。 実行すると、



このような画面を表示します。
入力ファイル選択ボタンで、ファイル選択ダイアログを開きます。
そこでファイルを選択すると、




このように画像のプレビューを表示します。

「塗り残す範囲の比率」を大きくすると、塗りつぶしする面積が狭くなります。

「ぼかし半径」を大きくすると、塗りつぶしの境界がぼけます。

「効果の強さ」を大きくすると、塗りつぶしがはっきりします。

「塗りつぶし色」を白にすると、周辺を白く塗りつぶしします。

「ファイル保存ボタン」をクリックすると、保存先選択ダイアログを開きます。


塗りつぶしを白に変更した例



2020年11月29日日曜日

Python+Pillowでトイカメラ風に周辺光量落ちさせる その1

最近、お出かけすることが減って、Pythonを勉強しています。
そのPython言語の、Pillowという画像ライブラリを使ったスクリプトです。
Pythonをインストールして、Pillowのライブラリをpipでインストールして
おく必要があります。
記事を書いている時点のPythonは3.8です。

前回までは、描画系のスクリプトを作りましたが、
今回から写真加工するスクリプトです。

【注意】
ファイルを書き出すスクリプトなので、
消えて困るファイルのあるフォルダでは実行しないでください。

以下にスクリプトのコードを書きます。


"""
トイカメラ風に周辺減光させる
Usage :
    python toycamera.py 入力画像 出力画像 塗り残す比率 ぼかし半径
起動パラメータ
    塗り残す比率 : 0.3 から 0.5 程度
    ぼかし半径 : 20 から 50 程度
             大きくすると塗りつぶしの境界がなだらかな調子になります
"""

import os
import sys
from PIL import Image, ImageDraw, ImageFilter

# 起動パラメータ数チェック
if len(sys.argv) < 3 :
    print("usage : python toycamera.py 入力ファイル 出力ファイル  塗り残す比率 ぼかし半径")
    sys.exit()

# 塗り残す範囲の比率
if len(sys.argv) > 3 :
    r_rate = float(sys.argv[3])
else:
    r_rate = 0.5
# ぼかし半径
if len(sys.argv) > 4 :
    blur_radius = int(sys.argv[4])
else:
    blur_radius = 50

if os.path.isfile(sys.argv[1]) is False :
    print("入力ファイル名にファイルではない名前が指定されています。")
    print("実行を中止します。")
    sys.exit()

if os.path.isdir(sys.argv[2]):
    print("出力ファイル名にディレクトリ名が指定されています。")
    print("実行を中止します。")
    sys.exit()

STRENGTH = 120               # 効果の強さ 0(最強)~255(効果なし)

print("以下の条件で処理を行います。")
print(f"入力ファイル {sys.argv[1]}")
print(f"出力ファイル {sys.argv[2]}")
print(f"塗り残す比率 {r_rate}")
print(f"ぼかし半径   {blur_radius}")
print(f"効果の強さ   {STRENGTH}")

inkey = input("よろしいですか?")
if inkey not in ("y", "Y") :
    print("実行を中止します。")
    sys.exit()

if os.path.exists(sys.argv[2]):
    print("\n出力ファイルが存在します。")
    inkey = input("上書きしてよろしいですか?")
    if inkey not in ("y", "Y") :
        print("実行を中止します。")
        sys.exit()

# 塗りつぶし色
# 白く塗りつぶす場合
#fill_color = (255, 255, 255)
# 黒く塗りつぶす場合
fill_color = (0, 0, 0)

# 画像を読み取り
im = Image.open(sys.argv[1])

# 円を描画する開始位置、終了位置を計算する
w,h = im.size
radius = max(w,h) * r_rate
w_start = (w / 2) - radius
w_end = (w / 2) + radius
h_start = (h / 2) - radius
h_end = (h / 2) + radius

# マスク画像を描画する
mask = Image.new("L", (w, h), STRENGTH)
draw = ImageDraw.Draw(mask)
draw.ellipse((w_start, h_start, w_end, h_end), fill=255)
mask_blur = mask.filter(ImageFilter.GaussianBlur(blur_radius))

# 塗りつぶし画像を作成する
plane = Image.new("RGB", (w, h), fill_color)

# 元の画像と、塗りつぶし画像を合成する
im2 = Image.composite(im, plane, mask_blur)
# 画像を表示
im2.show()
im2.save(sys.argv[2], quality=100)


上のスクリプトをUTF-8のエンコーディングで、toycamera.py という
ファイルに保存します。
Windowsだとコマンドプロンプト等を開いて、スクリプトを保存した


フォルダにcdコマンドで移動して、

python toycamera.py 入力画像名 出力画像名 塗り残す比率 ぼかし半径

で実行します。 実行すると、

  以下の条件で処理を行います。
    (中略)
  よろしいですか?

という確認メッセージを表示するので、
Y をキー入力すると、ファイルを加工して出力します。

入力画像の例






出力画像の例



この例は、
塗り残す比率 : 0.4
ぼかし半径 : 40
で作成しました。

スクリプト内の、 STRENGTH を変更すると塗りつぶしの強さが変わります。
また、 fill_color を (0,0,0) から (255,255,255) に変更すると、
周辺を白く加工します。



金曜日の夕方に、近所のハードオフで、Washburn XB200という
エントリクラスのベースギターのジャンク品を\5500で購入しました。

先週の3連休に見つけたものですが、トーンの可変抵抗の
ナットが無く、ボディの中に落ちてしまっているため
ジャンク品ということでした。
お店にチューナーを持っていって、チューニングしてみたところ、
ブリッジを目いっぱい下げているのに、弦の高さがすごく高くて
その時は、購入を見送りました。

でも、持った感じが軽くて弾きやすそうな感じがしたし、
ネック自体はまっすくだったし、
ネックの裏側がグロス仕上げで高級感があったので、
気になっていました。
あと、ブリッジがGOTOH製のものが付いていて、
最悪、部品取りすれば、丸損にはならないというのもあります。

弦高の問題は、ネックとボディのジョイント部分にシムを
入れたら、治るのではと気がついたので、購入に至りました。

金曜の夕方に買って、表面を掃除して、ジョイントを
外すと、メーカーで入れたと思われるシムが既に入っていたの
ですが、ボディ側の木材がシムの形に凹んでいて、
シムを入れた意味が無くなってしまっていました。

手元にあった厚紙を3枚重ねてネックとボディの間に入れたら、
弦高が正常になったのですが、そこに至るまでに、
厚紙の枚数を変えてジョイントのネジを締めて
チューニングを合わせて・・・というのを
4回ぐらいやりました。

あとは、弦、ブリッジ、ボリューム、つまみ、ピックアップを止めるビス、
ピックアップ用クッション、ジャックを交換し、ペグがぐらつくので
グリスを少し入れて現在に至ります。

このベース、前ピックアップと後ピックアップ用に
ボリュームがあるのに、バランス用の可変抵抗も
付いているのが珍しいです。
バランス用の可変抵抗にコンデンサも付いているので、
ハイパスのトーンかと思ったのですが、使ってみると
PUバランスだったという。

2020年11月22日日曜日

Python+PillowでRGBスケールを描画する

 最近、お出かけすることが減って、Pythonを勉強しています。

そのPython言語の、Pillowという画像ライブラリを使ったスクリプトです。

Pythonをインストールして、Pillowのライブラリをpipでインストールしておく

必要があります。

記事を書いている時点のPythonは3.8です。


前回はいろいろな大きさの円形をランダムな位置に描画するスクリプトを作りました、

今回は赤、緑、青、灰色の色スケールを描画するスクリプトです。


以下にスクリプトのコードを書きます。




"""
PillowでRGBスケールを描画する
"""

import random
from PIL import Image, ImageDraw

def main():
    """
    画像作成処理
    """

    BLOCK_WIDTH = 100                  # ブロックの幅
    BLOCK_GAP = 5                      # ブロック間の幅
    IMG_WIDTH = 4*BLOCK_WIDTH + 3*BLOCK_GAP  # 画像の幅
    BLOCK_HEIGHT = 32                   # ブロックの高さ
    BLOCK_STEP = 16                     # ブロックの色の増分
    IMG_HEIGHT = int(BLOCK_HEIGHT*(256/BLOCK_STEP+1))  # 画像の高さ
    BACKGROUND = (255, 255, 255)       # 背景色

    # 画像を作成
    im = Image.new("RGB", (IMG_WIDTH, IMG_HEIGHT), BACKGROUND)
    draw = ImageDraw.Draw(im)

    # 4つの色で繰り返し描画する
    pos_x_st = 0
    for i in range(4):
        if i > 0 :
            pos_x_st = pos_x_st + BLOCK_WIDTH + BLOCK_GAP
        pos_x_en = pos_x_st + BLOCK_WIDTH

        # 色ごとに明るさを変えて描画する
        light = 0
        r = 0
        g = 0
        b = 0
        for j in range(int(256 / BLOCK_STEP + 1)):
            pos_y_st = j * BLOCK_HEIGHT
            pos_y_en = (j+1) * BLOCK_HEIGHT

            # 各色 36から255の乱数を生成
            if i == 0 :
                # 赤スケール
                r = light
            elif i == 1 :
                # 緑スケール
                g = light
            elif i == 2 :
                # 青スケール
                b = light
            else :
                # 白黒スケール
                r = light
                g = light
                b = light

            # 1つのブロックを描画する
            draw.rectangle((pos_x_st, pos_y_st, pos_x_en, pos_y_en), (r,g,b))

            # 次のブロックの明るさを計算する
            light = light + BLOCK_STEP
            if light > 255 :
                light = 255

    # 画像を保存
    im.save("rgb_scale.png")

    # 画像を表示
    im.show()

if __name__ == '__main__':
    # 画像作成処理を実行
    main()




上のスクリプトをUTF-8のエンコーディングで、拡張子 .py のファイルにして保存します。

Windowsだとコマンドプロンプト等を開いて、スクリプトを保存したフォルダにcdコマンドで移動して、


python スクリプトファイル名


で実行します。 実行すると、



こんな感じの画像が表示されると思います。


スクリプトの中の、BLOCK_HEIGHT を 32 から 4 に、

BLOCK_STEP を 16 から 2 に変更して、実行すると、

こんな感じの画像になります。



出力画像の大きさが少し変わってしまうのは、ご愛敬ということで。


まじめにディスプレイの調整をしたいのであれば、

https://www.eizo.co.jp/eizolibrary/other/itmedia04/

こちらのページから、いろいろな確認用の画像が入手できます。


2020年11月15日日曜日

ご近所のヒガンバナ

9月29日のお散歩写真です。

ご近所の緑地まで歩いてきました。



ご近所の公園の植え込みのヒガンバナ。



緑地に移動しました。

木が茂っていて、昼でも薄暗いので、撮りにくいです。

この緑地の中に、白い花と赤い花が植えてあるのですが、

今年は、ここの赤い花は状態が良くなかったです。



緑地内を移動中に見つけました。





緑地の逆側にも、少しだけヒガンバナが咲くので、それを撮りました。

Panasonic DMC-GX7, SIGMA MACRO 105mmF2.8 EX, Nikon F-M4/3アダプタ

ストロボ Pansonic PE-36S


2020年11月8日日曜日

Python+Pillowでいろいろな大きさの円を描く

最近、お出かけすることが減って、Pythonを勉強しています。 
そのPython言語の、Pillowという画像ライブラリを使ったスクリプトです。 
Pythonをインストールして、Pillowのライブラリをpipでインストールしておく
必要があります。 
記事を書いている時点のPythonは3.8です。

前回は同じ大きさの円形を並べて描画するスクリプトを作りましたが、 
今回はランダムな位置に、違う大きさの円形を描画します。 
円形を描画するには、Pilowの ImageDraw.Drawクラスの ellipse メソッド を使います。 以下にスクリプトのコードを書きます。

"""
Pillowで大きさを変えた円を多数描画する
"""

import random
from PIL import Image, ImageDraw

def main():
    """
    画像作成処理
    """

    IMG_WIDTH = 640                    # 画像の幅
    IMG_HEIGHT = 640                   # 画像の高さ
    BLOCK_SIZE = 15                    # 円の直径
    BLOCK_MIN = 10                     # 円の直径の最小値
    BACKGROUND = (255, 255, 255)       # 背景色
    NUM_CIRCLES = 100                  # 描画する円の個数

    # 画像を作成
    im = Image.new("RGB", (IMG_WIDTH, IMG_HEIGHT), BACKGROUND)
    draw = ImageDraw.Draw(im)

    # 円を繰り返し描画する
    for i in range(NUM_CIRCLES):
        pos_x = int(random.random() * IMG_WIDTH)
        pos_y = int(random.random() * IMG_HEIGHT)

        block = int(((NUM_CIRCLES - i) / NUM_CIRCLES) * BLOCK_SIZE) ** 2 + BLOCK_MIN
        # 各色 36から255の乱数を生成
        r = int(random.random()*256)
        g = int(random.random()*256)
        b = int(random.random()*256)
        draw.ellipse((pos_x - block, pos_y - block, pos_x + block, pos_y + block), (r,g,b))

    # 画像を表示
    im.show()

if __name__ == '__main__':
    # 画像作成処理を実行
    main()

上のスクリプトをUTF-8のエンコーディングで、拡張子 .py のファイルにして保存します。
 Windowsだとコマンドプロンプト等を開いて、スクリプトを保存したフォルダにcdコマンドで移動して、 

python スクリプトファイル名 

で実行します。 実行すると、




 こんな感じの画像が表示されると思います。

2020年11月1日日曜日

Python+Pillowで小さな円を並べて描画する

 最近、お出かけすることが減って、Pythonを勉強しています。

そのPython言語の、Pillowという画像ライブラリを使ったスクリプトです。

Pythonをインストールして、Pillowのライブラリをpipでインストールしておく必要があります。


前回は1ピクセルごとに色を設定する処理を繰り返して四角形を

作りましたが、今回は円形を描画します。

円形を描画するには、Pilowの?ImageDraw.Drawクラスの ellipse メソッド

を使います。

以下にスクリプトのコードを書きます。


"""
Pillowで小さな円を並べた画像を生成する
"""

import random
from PIL import Image, ImageDraw

def main():
    """
    画像作成処理
    """

    IMG_WIDTH = 640                    # 画像の幅
    IMG_HEIGHT = 640                   # 画像の高さ
    BLOCK_SIZE = 64                    # 円の直径
    BACKGROUND = (255, 255, 255)       # 背景色
    width = int(IMG_WIDTH / BLOCK_SIZE) * BLOCK_SIZE
    height = int(IMG_HEIGHT / BLOCK_SIZE) * BLOCK_SIZE

    # 画像を作成
    im = Image.new("RGB", (width+1, height+1), BACKGROUND)
    draw = ImageDraw.Draw(im)

    # 小さな円を繰り返し描画する
    start_pos = int(BLOCK_SIZE/2)
    for i in range(0, width, BLOCK_SIZE):
        for j in range(0, height, BLOCK_SIZE):
            r = int(random.random()*256)
            g = int(random.random()*256)
            b = int(random.random()*256)
            draw.ellipse((i,j,i+BLOCK_SIZE,j+BLOCK_SIZE), (r,g,b))

    # 画像を表示
    im.show()

if __name__ == '__main__':
    # 画像作成処理を実行
    main()

上のスクリプトをUTF-8のエンコーディングで、拡張子 .py のファイルにして保存します。

Windowsだとコマンドプロンプト等を開いて、スクリプトを保存したフォルダにcdコマンドで移動して、


python スクリプトファイル名


で実行します。

実行すると、




こんな感じの画像が表示されると思います。





2020年10月26日月曜日

Python+PillowでRGBノイズ画像を生成する

 最近、お出かけすることが減って、Pythonを勉強しています。

最終的には、Gimp-Pythonのスクリプトを自作できるようになれたらいいなと

思ったりしますが、Gimp-PythonってPython2でしか動かないっぽい?


Pythonというのは、プログラム言語の一つで、基本情報処理技術者試験に

採用されるほど業界で普及しているらしいです。

そのPython言語の、Pillowという画像ライブラリを使ったスクリプトです。

Pythonをインストールして、Pillowのライブラリをpipでインストールしておく必要があります。

以下にスクリプトのコードを書きます。


2020年10月11日日曜日

ご近所のツユクサ

9月19日のお散歩写真です。
ご近所を散歩しました。



青梅線の線路沿いにツユクサが咲いていて、
出勤する時に横目で見ていましたが、
やっと撮ることができました。
ツユクサは早起きしないと撮れないから、
撮る機会があまりないです。



夕方に、ご近所の緑地のヒガンバナの様子を見てきました。
白いリコリスはいつも赤いのより早く開花します。


こんな色のリコリスは初めて見ました。
この日は様子見だけのつもりだったので、
半袖で虫除けしなくて行ったら、ヤブ蚊に
猛襲されたので、そそくさと引き返しました。
Panasonic DMC-GX7, SIGMA 105mmF2.8 MACRO
Nikon F-M4/3マウントアダプタ, ストロボ Panasonic PE-36S

2020年9月22日火曜日

ご近所のガクアジサイ

6月20日のお散歩写真の続きです。
ご近所を散歩しました。
曇っていたので、あまり撮る気なしで、
とりあえずソフトレンズを付けて歩きました。







Panasonic DMC-GX7, Kenko 85mmF2.5soft、中間リング、
Nikon F-M4/3マウントアダプタ


2020年8月16日日曜日

ご近所の白い花

 6月20日のお散歩写真です。

ご近所を散歩しました。

曇っていたので、あまり撮る気なしで、

とりあえずソフトレンズを付けて歩きました。



近所の公園のアベリア




トキワツユクサは花が増えていましたが、

光線の状態が良くないのと、ヤブ蚊がいるので

少しだけ撮りました。



ドクダミ



インドハマユウ

名前は「アフリカハマユウ」が正しいらしいですが。

ここまで、ソフトレンズ使用です。




夕方、少し光線が良かったので、マクロレンズを付けて

インドハマユウを撮り直しました。

Panasonic DMC-GX7, Kenko 85mmF2.5soft、中間リング、

SIGMA MACRO 105mmF2.8 DG EX、Nikon F-M4/3マウントアダプタ


2020年6月21日日曜日

ご近所のトキワツユクサ

5月17日のお散歩写真です。
ご近所を散歩しました。
小作駅近くでピラカンサスを撮ったあと
多摩川の方に歩いて、グリーントリム公園
を通り抜けて羽加美緑地へ。







緑地内にトキワツユクサが群生しています。
まだ少し早い感じでしたが、手を伸ばすようにして
撮影しました。



緑地からの帰りに、タラノキっぽい木を見つけました。
こんな自宅の近くに生えているとは思いませんでした。

Panasonic DMC-GX7, SIGMA 105mmF2.8 Macro、 Nikon F-M4/3マウントアダプタ

2020年6月7日日曜日

ご近所のピラカンサス

5月17日のお散歩写真です。
ご近所を散歩しました。







小作駅近くの、桜が多い公園の植え込みに
ピラカンサスを見つけました。
ちょっと時期が遅かったかなぁって感じで
良いコンディションの花は少なかったです。
光線の状態が悪かったのをレタッチで補正してみました。




小作駅近くから多摩川の方に歩いて、グリーントリム公園へ。
ジャーマンアイリスが咲いていました。

Panasonic DMC-GX7, SIGMA 105mmF2.8 Macro、 Nikon F-M4/3マウントアダプタ



5月上旬から続いた在宅勤務も先週で終わり、
明日から過酷な長距離通勤が復活します。
体がすっかりなまっているような気がして、ちょっと不安です。
テレワークでは、チャットで乱暴なことを言ってくるお客さんが
居たりして、体は楽ですが、精神的に疲れますね。

2020年5月24日日曜日

こでまり公園のコデマリ

5月2日のお散歩写真の続きです。
ご近所のこでまり公園まで歩いてきました。











Panasonic DMC-GX7, Tokkina 100mmF2.8 MACRO, Nikon F-M4/3アダプタ



この日、歩いた印象で、5月連休は散歩している人が増えた感じがしていましたが、
昨日近所を歩いたら、もっと人が多くなっているような気がしました。
最近は東京の新規感染者数が少なくて、この調子で終息してくれると良いですね。

2020年5月3日日曜日

stay home

5月2日の写真です。




近所に出かけてみようかと、カメラを持ち出したところで、
アパートの玄関先に生えていたハルジョオンを撮りました。
Panasonic DMC-GX7, Tokkina 100mmF2.8 MACRO, Nikon F-M4/3アダプタ



4月29日から8連休のGWです。
4月はずっと体調が悪くて、まだ不調が続いています。
おかげで、近所のスーパーに出かける程度で、遊びに出かけることもなく
部屋で過ごしています。
5月連休に入ってからは、近所を歩いていても、すれ違う人が増えているように感じます。

2020年4月5日日曜日

ご近所の花あれこれ

3月21日のお散歩写真です。
ご近所を散歩しました。









この前日にも撮った公園のヤマザクラです。
ヤマザクラは3連休に咲いてくれて、撮ることができたのに、
ソメイヨシノはいい時に出かけられず、今年は撮っていません。



ツツジも咲き始めていました。






シダレモモ




畑に菜の花が植えてありました。




スイセンとハナニラ
Panasonic DMC-GX7, Tamron 180mmF3.5 Macro、 Nikon F-M4/3マウントアダプタ




4月3日から、自分も在宅勤務になってしまいました。
3.11の時には、拝島駅から電車が全日運休になっていても、
「出社しなさい」の電話がかかってくる会社なので、
テレワークなんて他人ごとだと思っていました。
毎朝の通勤電車に乗らなくて良いのは楽だけど、
出社日にパソコン持って行くの、しんどいなぁ。