7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

新規開発や新技術の検証、導入にまつわる記事を投稿しよう!

PNG に編集ソースファイルを埋め込んで再編集可能にする その2

Last updated at Posted at 2023-07-20

「PNG に編集ソースファイルを埋め込んで再編集可能にする その1」
https://qiita.com/nanbuwks/items/1af5b5ec87ebbe2a7712

では LibreOffice を使って、 Qiita に貼った png ファイルに編集ソースを埋め込む仕組みを解説しました。

開発中のヘルパーアプリはその2以降で解説します。

と書きましたが、今回は png ファイルから元ファイルを復元するためのヘルパーアプリを python で作成しました。

環境

  • Ubuntu 20.04 LTS

Python プログラム


#!/usr/bin/env python3
import json
import base64
import sys
import subprocess
import datetime
import platform
import os
import png


tempdir = '/tmp'
now = datetime.datetime.now()
pf = platform.system()
if pf == 'Windows':
    tempdir = os.environ['TEMP']
    dir = tempdir+"\\embpng"+now.strftime('%Y%m%d%H%M%S%f' )+"\\"
    os.makedirs(dir)
elif pf == 'Darwin':
    dir = tempdir+"/embpng"+now.strftime('%Y%m%d%H%M%S%f' )+"/"
    os.makedirs(dir)
elif pf == 'Linux':
    dir = tempdir+"/embpng"+now.strftime('%Y%m%d%H%M%S%f' )+"/"
    os.makedirs(dir)


reader = png.Reader(filename=sys.argv[1])
chunks = reader.chunks()
chunk_list = list(chunks)
find = 0
for item in chunk_list:
    if ( ord('t') == item[0][0] and ord('E') == item[0][1] and ord('X') == item[0][2] and ord('t') == item[0][3]  ):
        if ( 0 == item[1][15] ):
            if  ( "Embedded Source" == item[1][0:15].decode('utf-8')):
                di=json.loads(item[1][16:].decode('utf-8'))
                find=1
                break
if ( 0 == find ):
    print ("no embedded png")
    exit()
#embpngchunk=chunk_list[1]
#di=json.loads(embpngchunk[1].decode('utf-8'))
#print(di)
#with open(sys.argv[1]) as f:
#    di = json.load(f)
#print(di['filename'])  
#print(di['file'])  
#print(base64.b64decode(di['file']).decode('utf-8'))
with open(dir+di['filename'], 'wb') as fo:
    fo.write(base64.b64decode(di['file']))
if pf == 'Windows':
    subprocess.Popen(["start",  dir ], shell=True)
elif pf == 'Darwin':
    subprocess.Popen(['open', dir ])
elif pf == 'Linux':
    subprocess.Popen(['open', dir ])

実行にあたり、png ライブラリが必要になります。

$ sudo pip install pypng

以下の png ファイルを使って試してみましょう。

embeddedpng.png

(2023/07/21 00:24現在 Qiitaに画像が貼れなくなっているみたいです。復旧次第貼ります。→ 2023/07/21 22:31 貼れました!)

これをダウンロードします。ファイル名が長くなるのでtestpng.pngとでも名前を点けて保存しましょう。

先の python プログラムを、testpng.png を指定して実行します。

./decodeembpng.py testpng.png

復元したLibreOfficeファイルが表示されます。

image.png

これを開くと、中身が編集できます。(下図はファイル名が異なっていますが、Qiitaの不具合のため画像が貼れず、昔の画像を使いまわしています。)

image.png

想定問答

Windowsは? Macは?

一応、Windows / Mac の場合を想定して分岐コードを書いてますが、検証がまだです。

GUIじゃないの?

「その5」あたりで・・・

どうして LibreOffice 拡張じゃないの?

埋め込み PNG の作成 は LibreOffice 拡張を用いてますが、復元は LibreOffice 以外のソースも行えるように考え、独立したアプリケーションとしました。LibreOffice 以外にも、回路CADや 分子構造式でもできるようにしていきたいと考えています。

どうしてファイルをファイルマネージャで表示するだけなの? ファイルを直接開かないの?

セキュリティリスクのため、一旦ファイルに落とすようにしています。

draw.io/diaglams.net の埋め込み png と紛らわしい

ヘルパーアプリのバージョンアップで、対応の予定です。

いいね! 勝手に使いたいな!

この形式のライセンスはPublicDomein としています
ファイルフォーマットは「PNG に編集ソースファイルを埋め込んで再編集可能にする その1」
https://qiita.com/nanbuwks/items/1af5b5ec87ebbe2a7712
にあります。
ご活用ください。

関連投稿

今回のプログラムは、以下の調査を元に作成しています。

PNG にテキストを埋め込む
https://qiita.com/nanbuwks/items/969642abde48bb272c25
Qiita に画像を貼る方法
https://qiita.com/nanbuwks/items/e0c9f02c1b556dde140a
python でエスケープ文字の入った JSON からコンテンツを復元する
https://qiita.com/nanbuwks/items/8a15ff646edc0e3aba7f

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?