[Python] 362 OpenAI DALL-E 3による画像生成

[Mac M2 Pro 12CPU, Ventura 13.6, Python 3.10.4]

DALL-E 3からAPIで使えるようになったので、早速試してみました。

生駒山近景を出力したところ存在しないロープウェイを含む景色でした。2回目は信仰の山らしく祠の画像でした。六甲山も出してみました。

どうも画のタッチが好みではありません。そこら辺を調整できれば、使い出がありそうです。

# openaiライブラリを導入済みの場合はアップグレードする(旧Verにはopenai.OpenAIがない)
pip install --upgrade openai
import os
from openai import OpenAI

# 環境変数からAPIキーを取得
api_key = os.getenv('CHATGPT_API_KEY')
if not api_key:
    raise ValueError("OpenAI API Keyが環境変数に設定されていません")

# APIキーを設定
os.environ["OPENAI_API_KEY"] = api_key

client = OpenAI()

response = client.images.generate(
  model="dall-e-3",
  prompt="大阪府・奈良県にある生駒山の近景",
  size="1024x1024",
  quality="standard",
  n=1,
)

image_url = response.data[0].url
print(image_url)
生駒山近景1
生駒山近景2
六甲山近景

[JavaScript] 19 Adobe XDのアイテムデータを取得するプラグイン作成 その5 作業手順 / UXP for Adobe XD / Pythonでjson化

[Mac M2 Pro 12CPU, Ventura 13.6]

作業手順をまとめておきます。

1.Adobe XDのデザインタブでXY座標を取得したい項目を選択する

2. メニューのプラグインからItemXYGetterを選択する。出力ファイルを指定して実行する。

3.出力されたtxtファイルをtxtTojson.pyで処理し、jsonファイルにする。

時間があればJavaScriptとPythonのスクリプトを統合し、JavaScriptのプラグインだけで処理できるようにしたいです。

※ ItemXYGetterのjsスクリプトの内容等は過去記事で紹介しています。画面左の検索窓で探してみてください。

Pythonスクリプトでjsonファイルに変換

[Python] 361 Excelセルの日付をシート名にする openpyxl

[Mac M2 Pro 12CPU, Ventura 13.6, Python 3.10.4]

Excelシートの1枚目A2セルにある日付をyymmdd形式に変換し、シート名にするスクリプトです。

ChatGPTのAPIが不調のため、以前のようにネット検索で調べました。やはりネット検索スキルはAI時代でも必須ですね。

import openpyxl
from openpyxl import load_workbook
from datetime import datetime, timedelta

def sheet_naming():
      import warnings
      warnings.simplefilter(action='ignore', category=UserWarning)

      # Excelファイルを読み込む
      file = 'test.xlsx'
      bk = openpyxl.load_workbook(file)

      # 先頭シートを取得 
      sheet = bk.worksheets[0]
      # 日付セルA2の値(5桁整数,表示はmm/dd)を取得
      date0 = sheet['A2'].value

      # date0をyymmdd形式に変換する
      date = datetime(1899, 12, 30) + timedelta(days=date0)
      date_str = date.strftime('%y%m%d')
      print("date_str: " + date_str)

      # シート名を変更する
      sheet.title = date_str
      # 変更を保存する
      bk.save(file)

[Python] 360 PDFファイルを結合

[Mac M2 Pro 12CPU, Ventura 13.6, Python 3.10.4]

PDFを色々加工するPythonスクリプトがたまってきました。

C++に移植してGUIアプリにまとめようかと考えています。

最近ファイル名やファイルパスを加工するのにosモジュールをよく使います。これまではsplitメソッドなどを使った文字列加工を多用していましたが、osモジュールのメソッドの方がさすがに使いやすいですね。

import os
from PyPDF2 import PdfMerger

# PDFファイルのディレクトリ
pdf_folder = '/images/'

# PDFファイルのリストを作成
pdf_files = [os.path.join(pdf_folder, f) for f in os.listdir(pdf_folder) if f.endswith('.pdf')]
pdf_files.sort()

# 先頭PDFファイル名を元に結合ファイル名を作成
pdf_name = os.path.splitext(pdf_files[0])[0] + "_join" + os.path.splitext(pdf_files[0])[1]
pdf_path = os.path.join(pdf_folder, pdf_name)

# PDFファイルを結合
merger = PdfMerger()
for pdf_file in pdf_files:
    merger.append(pdf_file)
merger.write(pdf_name)
merger.close()

[Python] 359 ファイル名の数字を引き算してリネーム

[Mac M2 Pro 12CPU, Ventura 13.6, Python 3.10.4]

画像ファイル名に含まれる数字を抽出して引き算しリネームするスクリプトを書きました。

下記スクリプトでは2桁の数字から2を引き算した新ファイル名にリネームしています。

import os, shutil

srcDir = "/images"
dstDir = "/images2" # 移動先

for filename in os.listdir(srcDir):
    if filename.endswith(".jpeg"):
        newName1 = (filename.split(".")[0]).split(" ")[0]
        newName2 = str(int((filename.split(".")[0]).split(" ")[1]) - 2).zfill(2)
        print(newName1 + newName2)
        
        new_filename = newName1 + " " + newName2 + ".jpeg"
        oldPath = os.path.join(srcDir, filename)
        print(oldPath)
        
        newPath = os.path.join(dstDir, new_filename)
        print(newPath)
        
        os.rename(oldPath, newPath)      # ファイル移動
        # shutil.copy2(oldPath, newPath) # ファイルコピー

[C++,Python] 316 BBS閲覧アプリの製作 その2 スレッドタイトルの取得 Python編

[M1 Mac, MacOS Ventura 13.3.1, Python 3.10.4]

スレッドタイトルとスレッドIDを取得するPythonスクリプトを書きました。

次はこのスクリプトをC++へ変換したいです。難しくなるようであればモジュール化します。

機能はPythonで下書きしてC++へ変換あるいはモジュール化、GUIはFLTK(C++)でコーディングしていきます。

import requests
import re
from bs4 import BeautifulSoup

# URLからHTMLファイルを取り込む
url = 'スレッドタイトル表示URL(HTMLファイル)'
response = requests.get(url)
response.encoding = response.apparent_encoding
html = response.text

# BeautifulSoupを使用してHTMLを解析する
soup = BeautifulSoup(html, 'html.parser')

# <small id="trad">タグで囲まれた部分の内容を取得する
trad_tags = soup.find_all('small', id='trad')

thread_list = []
for trad_tag in trad_tags:
    content = trad_tag.get_text()

    # <a>タグのhref属性の値を正規表現で取得する
    pattern = r'<a\s+href=[\'"]([^\'"]+)[\'"]'
    href = re.findall(pattern, str(trad_tag))

    # contentをaタグごとに分割してリストにする
    content_list = re.split(r'<a\s+href=[\'"][^\'"]+[\'"]', str(trad_tag))
    
    print(f"hrefの要素数: {len(href)}")
    print(f"content_listの要素数: {len(content_list)}")

    # 辞書型データのリストを作成する
    for i in range(len(href)):
        thread_list.append({'href': (href[i])[:-4], 'content': (content_list[i+1].strip().replace("</a>","").replace("</small>",""))[1:]})

# リストの内容を出力する
for thread in thread_list:
    print(thread['href'])
    print(thread['content'])

[C++,Python] 315 BBS閲覧アプリの製作 その1 DATファイルの保存

[M1 Mac, MacOS Ventura 13.3.1, clang 14.0.3]

とあるBBSのDATファイルへのアクセスが可能になったようなので、早速遊んでみることにしました。

とりあえずDATファイルをダウンロードしてみます。PythonスクリプトをChatGPTに変換してもらったコードがそのまま使えました。

DATファイルの文字コードがシフトJISですから、Macの場合はUTF-8に変換する必要がありますね。

#include <iostream>
#include <fstream>
#include <curl/curl.h>

size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    std::ofstream* file = static_cast<std::ofstream*>(userp);
    file->write(static_cast<char*>(contents), size * nmemb);
    return size * nmemb;
}

int main() {
    std::string url = "DATファイルのurl";
    std::string filename = "保存先DATファイルのパス";

    CURL* curl = curl_easy_init();
    if (curl) {
        std::ofstream file(filename, std::ios::binary);
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &file);
        CURLcode res = curl_easy_perform(curl);
        if (res != CURLE_OK) {
            std::cerr << "Error: " << curl_easy_strerror(res) << std::endl;
        }
        curl_easy_cleanup(curl);
    } else {
        std::cerr << "Failed to initialize curl" << std::endl;
    }

    return 0;
}

[Python] 358 pngファイルからαチャンネルを削除

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

前の記事でiOSアプリはアイコン登録で優遇されているのではないかと述べましたが、案外そうでもなさそうです。

というのは、iOSアイコンとして登録する画像はpngはpngでもαチャンネル(透過度)を削除したpngでないとアプリ申請が通らないからです。

αチャンネルがないpngというのが存在するというのも驚きですし、それを必須にするAppleもたいがいだと感じました。

αチャンネルはPythonで簡単に削除できます。

from PIL import Image

def remove_alpha_channel(input_file, output_file):
    image = Image.open(input_file)
    image = image.convert("RGB")
    image.save(output_file)

input_file = "RGBA.png"
output_file = "RGB.png"
remove_alpha_channel(input_file, output_file)

削除できたかどうかは右メニュー”情報を見る”、あるいはピクセル情報をCSVファイルに出力すれば分かります。RGBAデータを取り出そうとするとエラーになるはずです。

“情報を見る”画面
from PIL import Image
import numpy as np
import csv

img_array = np.array(Image.open("RGB.png"))

# 全ピクセルの色情報を取得 jpgあるいはpng(RGB)の場合
list_rgb = img_array[:, :, (0, 1, 2)]
# png(RGBA)の場合
# list_rgba = img_array[:, :, (0, 1, 2, 3)]

with open("RGB.csv", 'w') as f:
    writer = csv.writer(f,lineterminator='\n')
    writer.writerows(list_rgb)

# アルファチャンネル

[Python] 357 画像に枠を描画

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

macOSのプレビューでは外枠を直接描けないようなので、Pythonで描きました。

下のスクリプトでは太さ2pxの黒い外枠を描画します。

C++画像加工アプリにこの機能を追加したいです。

import cv2
import numpy as np

# 画像ファイル設定
pic_name="test.PNG"
pic_name_out="test2.PNG"

# 枠ピクセル数
num_insert=2

# 画像読み込み
img = cv2.imread(pic_name,cv2.IMREAD_COLOR)

# 枠追加処理(上下)
bk1=np.zeros((num_insert,img.shape[1],3),np.uint8)

# 上下枠色設定
bk1[:,:,0]=bk1[:,:,0]+0 # 青
bk1[:,:,1]=bk1[:,:,1]+0 # 緑
bk1[:,:,2]=bk1[:,:,2]+0 # 赤
array=np.insert(img, 0, bk1, axis=0)
array=np.insert(array, array.shape[0], bk1, axis=0)

# 枠追加処理(左右)
bk2=np.zeros((array.shape[0],num_insert,3),np.uint8)

# 左右枠色設定
bk2[:,:,0]=bk2[:,:,0]+0 # 青
bk2[:,:,1]=bk2[:,:,1]+0 # 緑
bk2[:,:,2]=bk2[:,:,2]+0 # 赤
array=np.insert(array, [0], bk2, axis=1)
array=np.insert(array, [array.shape[1]], bk2, axis=1)

# 画像出力
cv2.imwrite(pic_name_out,np.array(array))

参考サイト

[Python] 356 HEICからPNGへの変換 iPhone画像 / HEIC2PNG

[M1 Mac, Ventura 13.3.1, Python 3.10.4]

iPhoneで撮影した画像はHEIC形式になります。

これをPNGファイルに変換するにはpyheifライブラリを使うのがメジャーのようですが、私の環境ではエラーが発生します。

そこで昨年9月にリリースされたheic2pngライブラリを使って変換しました。

pip install HEIC2PNG
from heic2png import HEIC2PNG

if __name__ == '__main__':
    img = HEIC2PNG('test.HEIC')
    img.save() # test.pngに変換