[Python]324 kindle本のpngファイル化

[M1 Mac, Big Sur 11.6.5]

kindle本の画集を壁紙にするためPythonでpngファイル化しました。結合したらpdfファイルにできそうです。

import pyautogui
import time

# ページ数
page = 100
# スクショ撮影間隔(秒)
span = 1
# 出力ファイル
filedir = "/Users/[ユーザ名]/Desktop/Manet"
file_prefix = "Manet"

# 10秒待機(この間にkindleをフルスクリーン表示させる)
time.sleep(10)

# スクショ撮影
for p in range(page):
    # 出力ファイル名(プレフィックス_3桁ゼロ埋め連番.png)
    filename = file_prefix + "_" + str(p + 1).zfill(3) + '.png'
    # 画面全体スクリーンショット
    s = pyautogui.screenshot()
    # png保存
    s.save(filedir + "/" + filename)
    # ページ送り(通常は左右)
    pyautogui.press('down')
    # 1秒待機
    time.sleep(span)

[Python]323 icnsファイルの作成

[M1 Mac, Big Sur 11.6.5]

MacOSアプリ用アイコンを作成する機会が増えたのでicnsファイル作成コードを書きました。あらかじめ2つのpngファイルを用意すればあとは自動的にicnsファイルを作成してくれます。

最初のpngファイル2つはプレビューアプリのサイズ調整機能で簡単に作れます。大元のファイルは2048*2048, dpi=72です。

from PIL import Image
import subprocess

filepath = 'test.png' # 1024*1024 dpi=144
filepath2 = 'test2.png' # 512*512 dpi=72
filedir = '/test/test.iconset/'
pixels = [32, 64, 256, 512, 1024]
pixels2 = [16, 32, 64, 256, 512]
filenames = ['icon_16x16@2x.png','icon_32x32@2x.png','icon_128x128@2x.png','icon_256x256@2x.png','icon_512x512@2x.png']
filenames2 = ['icon_16x16.png','icon_32x32.png','icon_128x128.png','icon_256x256.png','icon_512x512.png']

# dpi=144の各種pngファイル作成
for pixel,file in zip(pixels,filenames):
    img = Image.open(filepath)
    img_resize = img.resize((pixel,pixel))
    img_resize.save(filedir + file)
    img.close()

# dpi=72の各種pngファイル作成    
for pixel,file in zip(pixels2,filenames2):
    img = Image.open(filepath2)
    img_resize = img.resize((pixel,pixel))
    img_resize.save(filedir + file)
    img.close()

# icnsファイル作成
cmd = 'iconutil -c icns test.iconset'
subprocess.run(cmd, cwd=r"/test",shell=True)

[Java]104 Makefileによるappファイル作成自動化

[M1 Mac, Big Sur 11.6.4]

これまで手動だったappファイル作成をMakefileにより自動化しました。

下記ファイルによりmakeコマンド一発でjarファイルを作成・署名し、appファイルを作成できます。これを応用してApple公証用zipファイル提出まで一気に実行することも可能でしょう。

# コンパイラ・ビルダ設定
COMPILER = javac
BUILDER = jar

# jarファイル設定
TARGET = test.jar
TARGETDIR = ../bin
MAIN_CLASS = Test

# jarファイル作成および署名,appファイル作成
$(TARGET):
	$(COMPILER) -d $(TARGETDIR) base/*.java -encoding utf-8
	cp -r ./images ../bin/images
	cp -r ./properties ../bin/properties
	cd $(TARGETDIR) && pwd && \
	$(BUILDER) cfe $@ base.$(MAIN_CLASS) \
		base/*.class \
		btn_action/*.class \
		xml/*.class \
		properties/*.* \
		images/*.png && \
	cp -f ../entitlements.plist entitlements.plist && \
	codesign --force --verify --verbose \
		--sign [mac-signing-key-user-name] \
		"test.jar" \
		--deep \
		--options runtime \
		--entitlements entitlements.plist \
		--timestamp
	cd .. && \
	jpackage --type app-image \
        --name test \
        --input bin \
        --main-jar test.jar \
        --icon bin/images/test.icns \
        --copyright "Copyright (C) 2021-2022" \
        --mac-signing-key-user-name [mac-signing-key-user-name] \
        --app-version "1.6.7" \
        --vendor [ベンダ名] \
        --runtime-image jre-mini

[C++] 07 FLTKのMakefile作成 appファイル作成箇所変更

[M1 Mac, Big Sur 11.6.4, FLTK 1.3.8]

Info.plistにできるだけ手を入れないよう、binディレクトリの実行ファイルをMakefileがあるsrcディレクトリにコピーしてからappファイルを作成しました。

実行ファイルをコピーして最後に消去するという工程が増えるのでコードの行数自体はさほど変わらないですが、plistファイルの中はあまりいじらない方を選択しました。今回はiconファイルの設定だけに留めています。ゆくゆくはバージョン番号やコピーライトを追記します。

Makefileの隣にappファイルが作成されるため、動作確認もすぐにでき効率的になりました。

<Makefileの一部>

# oファイルから実行ファイルとappファイル作成
$(TARGET): $(OBJECTS)
	$(COMPILER) -o $(TARGETDIR)/$@ $(OBJECTS) $(LINK) $(LDFLAGS)
	cp $(TARGETDIR)/$(TARGET) $(TARGET)
	$(POSTBUILD) $(TARGET)
	mkdir $(TARGET).app/Contents/Resources
	cp ../images/ColorSampleJP.icns $(TARGET).app/Contents/Resources
	plutil -insert 'CFBundleIconFile' -string "test.icns" $(TARGET).app/Contents/Info.plist
	rm -f $(TARGET)

[C++] 06 ウィジェットツールキットの比較

C++で使える主なウィジェットツールキットを比較しました。

wxWidgetsもお手頃ですが、OSのLook & Feelを採用しているのが私にはネックです。個人的にWindowsのL&Fが好みではありません。ファイルサイズが大きいというのもマイナスです。

当初の予定通り、FLTKで進めていくことにしました。

[C++] 05 FLTKのMakefile作成 Info.plistの修正

[M1 Mac, Big Sur 11.6.4, FLTK 1.3.8]

Makefileを更新しました。

“fltk-config –post”コマンドではMakefileと実行ファイルが同じディレクトリにないとappファイル内に作成されるInfo.plistの内容がおかしくなります。相対パスがMakefile基準なので修正する必要があります。

そのため一旦作成されたInfo.plistを修正するコマンドを追加しました。iconファイルを設定するキーも追加しています。

# コンパイラ設定他
COMPILER = clang++
DEBUG = -g

# フラグ設定
CXXFLAGS = $(shell fltk-config --use-gl --use-images --cxxflags ) -std=c++11
LDFLAGS = $(shell fltk-config --use-gl --use-images --ldflags ) -lc++ 

# includeパス設定
INCLUDE = -I../include -I/opt/homebrew/Cellar/fltk/1.3.8/include

# linkパス設定
LINK = -L/opt/homebrew/Cellar/jpeg/9e/lib -L/opt/homebrew/Cellar/libpng/1.6.37/lib

# 実行ファイル設定
TARGET = test
TARGETDIR = ../bin

# ソースコードパス
SRCROOT   = .

# oファイルの出力ディレクトリ
OBJROOT   = ../obj

# ソースディレクトリのリスト化
SRCDIRS := $(shell find $(SRCROOT) -type d)

# ソースディレクトリから全てのcppファイルをリスト化
SOURCES   = $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.cpp))

# cppファイルのリストからオブジェクトファイル名を設定
OBJECTS   = $(addprefix $(OBJROOT), $(patsubst ./%,/%,$(SOURCES:.cpp=.o)))

# oファイルの出力ディレクトリをリスト化
OBJDIRS   = $(addprefix $(OBJROOT), $(patsubst ./%,/%,$(SRCDIRS)))

# 依存dファイルをoファイルから作成
DEPENDS   = $(OBJECTS:.o=.d)

# 依存ファイル
-include $(DEPENDS)

# cppファイルからoファイル作成
$(OBJROOT)/%.o: $(SRCROOT)/%.cpp
	@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
	$(COMPILER) $(CXXFLAGS) $(INCLUDE) $(DEBUG) -o $@ -c $<

# アプリファイル作成関連
POSTBUILD  = fltk-config --post

# oファイルから実行ファイルとappファイル作成
$(TARGET): $(OBJECTS)
	$(COMPILER) -o $(TARGETDIR)/$@ $(OBJECTS) $(LINK) $(LDFLAGS)
	$(POSTBUILD) $(TARGETDIR)/$@
	mkdir $(TARGETDIR)/$(TARGET).app/Contents/Resources
	cp ../images/test.icns $(TARGETDIR)/$(TARGET).app/Contents/Resources
	plutil -replace 'CFBundleExecutable' -string "test" $(TARGETDIR)/$(TARGET).app/Contents/Info.plist
	plutil -insert 'CFBundleIconFile' -string "test.icns" $(TARGETDIR)/$(TARGET).app/Contents/Info.plist
	plutil -replace 'CFBundleIdentifier' -string "org.fltk.test" $(TARGETDIR)/$(TARGET).app/Contents/Info.plist

[C++] 04 FLTK:Fl_Tabs, Fl_Group, Fl_Button

[M1 Mac, Big Sur 11.6.1, FLTK 1.3.8]

自製GUIアプリの移植に本格着手しました。まずはFL_Buttonの格子状配置です。

もっと苦労するかと思いましたが、案外すんなりでした。Java・SwingのGridBagLayoutを使うより断然書きやすいです。ただ日本語ユーザーでFLTKを使っている方はネットではほとんど見かけず、少ない英語情報を参考に基本的には自分でマニュアルを読みながら進めていくという形になります。

FL_Buttonのconst char*型引数を作成する所で配列の要素をそのまま渡すと配列の最後の文字列が全てのボタンに表示されてしまうというトラブルがありましたが、要素のポインタを渡すと各々の文字列が問題なく表示されました。ポインタはしばらく扱っていなかったので慣れるまで少し時間がかかりそうです。

移植開始前、C/C++とJavaは似ても似つかぬ言語だという印象でした。書き進めていくとFor文の書き方や配列からの値の取り出し方などC/C++がJavaにかなりの影響を与えているところが垣間見え、徐々に親しみが湧いてきました。

ネットにてC言語の様々な自作関数を目にしますが、実はC++では正式な関数として用意されているといったケースが多々あり、余計な遠回りをしないよう注意を払う必要があります。

今回は危うくsubstr関数を自製しようとしましたし、16進数の文字列を数値に変換する際、C++11から採用のstoiを使わずにatoiで処理しかけました。C言語専門あるいはC++11以降を知らない方も多くいらっしゃるようです。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Widget.H>

using std::cout; using std::cin;
using std::endl; using std::string;
using std::vector; using std::stoi;

int main(int argc, char **argv) {
    Fl_Window *window = new Fl_Window(50,50,660,480);

    <色名などの配列は省略>

    Fl_Tabs *tabs = new Fl_Tabs(10,10,400,480);
    {
        for (auto &i : tab_names) {
            string tab_name = i;
            const char* tab_name_p = i.c_str();
            Fl_Group *grp = new Fl_Group(30,30,380,440,tab_name_p);{
                int num = 0;
                grp->labelsize(10);
                for (int x = 0; x < 5; x++){
                    int loc_x = x * 75 + 23;
                    for (int y = 0; y < 28; y++){
                        int loc_y = y * 15 + 43;

                        string* color_name_p = &(color_names[num]);
                        const char* color_name_p2 = color_name_p->c_str();

                        string color_code = color_codes[num];
                        string red0 = color_code.substr(2,2);
                        int red = stoi(red0, nullptr, 16);
                        
                        string green0 = color_code.substr(4,2);
                        int green = stoi(green0, nullptr, 16);

                        string blue0 = color_code.substr(6,2);
                        int blue = stoi(blue0, nullptr, 16);

                        Fl_Button *button = new Fl_Button(loc_x, loc_y, 75, 15,color_name_p2);
                        button->color(fl_rgb_color(red,green,blue));
                        button->labelcolor(fl_rgb_color(169,169,169));
                        button->labelsize(8);
                        num = num + 1;
                    }
                } 
            }
            grp->end();
        }
    }
    tabs->end();
    
    window->end();
    window->show(argc, argv);
    return Fl::run();
}

[C++] 03 FLTKのMakefile作成 サブディレクトリへの対応

[M1 Mac, Big Sur 11.6.1, FLTK 1.3.8]

自製アプリのJavaからC++への移植にあたり、複数ソースコード・複数サブディレクトリに対応したMakefileを作成しました。参考サイトの記事がなければ何日掛かったか分かりませんね。本当に感謝です。

appファイルを作成するには、カレントディレクトリをbinに変更し、”fltk-config –post [実行ファイル]”コマンドを使います。

CMakeという便利なツールがあることを途中で知りましたが、もうMakefileを作ってしまったのでこのまま進めます。趣味としてプログラミングを楽しまれるのであればMakefileの自作をお勧めします。

これでコーディングに専念できる環境がほぼ整いました。

# コンパイラ設定他
COMPILER = clang++
DEBUG = -g

# フラグ設定
CXXFLAGS = $(shell fltk-config --use-gl --use-images --cxxflags )
LDFLAGS = $(shell fltk-config --use-gl --use-images --ldflags ) -lc++ 

# includeパス設定
INCLUDE = -I../include -I/opt/homebrew/Cellar/fltk/1.3.8/include

# linkパス設定
LINK = -L/opt/homebrew/Cellar/jpeg/9e/lib -L/opt/homebrew/Cellar/libpng/1.6.37/lib

# 実行ファイル設定
TARGET = test
TARGETDIR = ../bin

# ソースコードパス
SRCROOT   = .

# oファイルの出力ディレクトリ
OBJROOT   = ../obj

# ソースディレクトリのリスト化
SRCDIRS := $(shell find $(SRCROOT) -type d)

# ソースディレクトリから全てのcppファイルをリスト化
SOURCES   = $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.cpp))

# cppファイルのリストからオブジェクトファイルをリスト化
OBJECTS   = $(addprefix $(OBJROOT), $(patsubst ./%,/%,$(SOURCES:.cpp=.o)))

# oファイルの出力ディレクトリをリスト化
OBJDIRS   = $(addprefix $(OBJROOT), $(patsubst ./%,/%,$(SRCDIRS)))

# cppファイルからoファイル作成
$(OBJROOT)/%.o: $(SRCROOT)/%.cpp
	@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
	$(COMPILER) $(CXXFLAGS) $(INCLUDE) $(DEBUG) -o $@ -c $<

# oファイルから実行ファイル作成
$(TARGET): $(OBJECTS)
	$(COMPILER) -o $(TARGETDIR)/$@ $(OBJECTS) $(LDFLAGS) $(LINK)

# 依存ファイル
-include $(DEPENDS)

# 全ソース強制コンパイル
all: clean $(TARGET)

# 全ファイル削除(cpp以外)
clean:
	rm -rf $(OBJDIRS) $(DEPENDS) $(TARGETDIR)/$(TARGET)

参考サイト

[C++] 02 FLTKのMakefile修正(appファイル作成)

[M1 Mac, Big Sur 11.6.1, FLTK 1.3.8]

昨日の段階ではmakeコマンドで実行ファイルを作成できませんでしたが、少し知識を仕入れたので更にその先のappファイルを一発作成できるようMakefileを修正しました。

Mac用であるappファイルはこのように簡単に作れます。ただWindowsストア用appxファイルはどうやったら作成できるのか。かなり難航しそうな予感がします。

Makefileの記述はぱっと見、取っつきにくいですが、そのうち慣れるでしょう。

CXX = $(shell fltk-config --cxx)
DEBUG = -g
CXXFLAGS = $(shell fltk-config --use-gl --use-images --cxxflags ) -I.
LDFLAGS = $(shell fltk-config --use-gl --use-images --ldflags ) -lc++ -L/opt/homebrew/Cellar/jpeg/9e/lib -L/opt/homebrew/Cellar/libpng/1.6.37/lib
LINK = $(CXX)
TARGET = test
OBJS = test.o
SRCS = test.cpp
.SUFFIXES: .o .cxx

# appファイル作成関連
STRIP      = strip
POSTBUILD  = fltk-config --post

# コマンド構成
%.o: %.cxx
	$(CXX) $(CXXFLAGS) $(DEBUG) -c $<
$(TARGET): $(OBJS)
	$(LINK) -o $(TARGET) $(OBJS) $(LDFLAGS)
	$(STRIP) $@
	$(POSTBUILD) $@

clean: $(TARGET) $(OBJS)
	rm -f *.o 2> /dev/null
	rm -f $(TARGET) 2> /dev/null

参考サイト:Article #599: Beginners Guide to fltk-config

[C++] 01 FLTKのMakefile作成

[M1 Mac, Big Sur 11.6.1, FLTK 1.3.8]

GUI作成ツールのFLTKをいじり始めました。今のところ非IDE環境です。

まずはHello WorldのMakefileをFLTKマニュアル(全1123ページの長編)を参考に作成しましたが、実行時エラーが発生しました。後で見ると–use-glや–use-imagesなど余計なオプションがあるものの、そのまま進めています。

試行錯誤の末、makeコマンド一発での実行ファイル作成をあきらめ、生成されたコマンドのオプションを修正し2つのコマンドで実行ファイルを作成しました。オプションに”-lc++”を追加することで”clang: error: linker command failed with exit code 1″の沼から脱しました。プログラミング強者が集うStack Overflow英語版のおかげです。なおこのオプション追加はIntel Macでも必要です。

Python, Javaと学んできてついに本丸のC++に到達しました。挫折しないようのんびり進めていきます。

CXX = $(shell fltk-config --cxx)
DEBUG =-g
CXXFLAGS = $(shell fltk-config --use-gl --use-images --cxxflags ) -I.
LDFLAGS = $(shell fltk-config --use-gl --use-images --ldflags )
LDSTATIC = $(shell fltk-config --use-gl --use-images --ldstaticflags )
LINK = $(CXX)
TARGET = test
OBJS = test.o
SRCS = test.cpp
.SUFFIXES: .o .cxx
%.o: %.cxx
	$(CXX) $(CXXFLAGS) $(DEBUG) -c $<
all: $(TARGET)
	$(LINK) -o $(TARGET) $(OBJS) $(LDFLAGS)
$(TARGET): $(OBJS)
test.o: test.cpp
clean: $(TARGET) $(OBJS)
	rm -f *.o 2> /dev/null
	rm -f $(TARGET) 2> /dev/null
# makeで作成したコンパイルとビルドのコマンド
# 後者から-lpngと-ljpegを削除して-lc++を追加(Intel Macでは削除不要)

clang++ -I/opt/homebrew/Cellar/fltk/1.3.8/include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -I. -c -o test.o test.cpp && \
cc -L/opt/homebrew/Cellar/fltk/1.3.8/lib -lc++ -lfltk_images -lz -lfltk_gl -framework OpenGL -lfltk -lpthread -framework Cocoa test.o -o test

# -lpngと-ljpegを削除しない場合は以下のコマンド(-Lオプション2つと-lc++追加)
clang++ -I/opt/homebrew/Cellar/fltk/1.3.8/include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -I.   -c -o test.o test.cpp && \
cc -L/opt/homebrew/Cellar/fltk/1.3.8/lib -L/opt/homebrew/Cellar/jpeg/9e/lib -L/opt/homebrew/Cellar/libpng/1.6.37/lib -lc++ -ljpeg -lpng -lfltk_images -lz -lfltk_gl -framework OpenGL -lfltk -lpthread -framework Cocoa  test.o   -o test