画像のリサイズの実験

背景

org2blogを使って、画像をアップロードするとサイズの関係で表示されないことがあるようだ。そこでPipaliにバッファ内の画像リンクをリサイズしたものに置き換える函数を書いてもらった。

Pipaliの出力

(require 'cl-lib)
(require 'org)
(require 'org-element)
(require 'subr-x)
(require 'url-util)

(defcustom snowfox/org2blog-image-max-dimension 500
  "縮小後の画像の最大幅・高さ。"
  :type 'integer)

(defcustom snowfox/org2blog-image-jpeg-quality 85
  "JPEG/WebPの縮小コピーに使う品質。"
  :type 'integer)

(defun snowfox/org2blog--imagemagick ()
  "ImageMagickの変換・識別コマンドを返す。"
  (cond
   ((executable-find "magick")
    (list :convert (executable-find "magick")
          :identify (executable-find "magick")
          :identify-prefix '("identify")))
   ((and (executable-find "convert") (executable-find "identify"))
    (list :convert (executable-find "convert")
          :identify (executable-find "identify")
          :identify-prefix nil))
   (t
    (user-error
     "ImageMagickが見つかりません(magick または convert/identify が必要です)"))))

(defun snowfox/org2blog--run (program args)
  "PROGRAMにARGSを渡して実行し、失敗したらエラーにする。"
  (with-temp-buffer
    (let ((status (apply #'call-process program nil t nil args)))
      (unless (and (integerp status) (= status 0))
        (error "%s" (string-trim (buffer-string))))
      (buffer-string))))

(defun snowfox/org2blog--dimensions (file imagemagick)
  "FILEの画像サイズを(width . height)で返す。"
  (let* ((prefix (plist-get imagemagick :identify-prefix))
         (program (plist-get imagemagick :identify))
         (output
          (snowfox/org2blog--run
           program
           (append prefix (list "-ping" "-format" "%w %h" file)))))
    (unless (string-match
             "\\`[[:space:]]*\\([0-9]+\\)[[:space:]]+\\([0-9]+\\)"
             output)
      (error "画像の縦横サイズを読み取れません: %s" file))
    (cons (string-to-number (match-string 1 output))
          (string-to-number (match-string 2 output)))))

(defun snowfox/org2blog--resize-copy (source imagemagick)
  "SOURCEの縮小コピーを作り、そのファイル名を返す。"
  (let* ((extension (file-name-extension source t))
         (ext (downcase (or (file-name-extension source) "")))
         (target
          (concat (file-name-sans-extension source)
                  "-web-"
                  (number-to-string snowfox/org2blog-image-max-dimension)
                  extension))
         (temp
          (make-temp-file
           (expand-file-name ".org2blog-resize-"
                             (file-name-directory target))
           nil extension))
         (args
          (append
           (list source
                 "-auto-orient"
                 "-resize"
                 (format "%dx%d>"
                         snowfox/org2blog-image-max-dimension
                         snowfox/org2blog-image-max-dimension))
           (when (member ext '("jpg" "jpeg" "webp"))
             (list "-quality"
                   (number-to-string snowfox/org2blog-image-jpeg-quality)))
           (list temp))))
    (unwind-protect
        (progn
          (when (and (file-exists-p target)
                     (not (yes-or-no-p
                           (format "既存の縮小コピーを上書きしますか? %s "
                                   target))))
            (user-error "上書きを取り消しました: %s" target))
          (snowfox/org2blog--run
           (plist-get imagemagick :convert)
           args)
          (rename-file temp target t)
          target)
      (when (file-exists-p temp)
        (delete-file temp)))))

(defun snowfox/org2blog--rewritten-link (record target base)
  "RECORDのOrgリンクをTARGETへのリンクにした文字列を返す。"
  (let* ((begin (plist-get record :begin))
         (end (plist-get record :end))
         (whole (buffer-substring-no-properties begin end))
         (raw (plist-get record :raw))
         (prefix (if (string-prefix-p "file:" raw) "file:" ""))
         (old-path (substring raw (length prefix)))
         (absolute (file-name-absolute-p old-path))
         (new-path
          (if absolute
              target
            (file-relative-name target base)))
         (new-path
          (if (and (string-empty-p prefix)
                   (not absolute)
                   (not (string-prefix-p "./" new-path))
                   (not (string-prefix-p "../" new-path)))
              (concat "./" new-path)
            new-path))
         (new-raw (concat prefix (org-link-escape new-path)))
         (position (string-match (regexp-quote raw) whole)))
    (unless position
      (error "Orgリンク内でリンク先を特定できません: %s" raw))
    (concat (substring whole 0 position)
            new-raw
            (substring whole (+ position (length raw))))))

(defun snowfox/org2blog-resize-images ()
  "Orgバッファ内の大きなローカル画像を縮小し、リンクを差し替える。"
  (interactive)
  (unless (derived-mode-p 'org-mode)
    (user-error "Orgバッファで実行してください"))
  (let* ((base
          (file-name-as-directory
           (expand-file-name
            (if buffer-file-name
                (file-name-directory buffer-file-name)
              default-directory))))
         (imagemagick (snowfox/org2blog--imagemagick))
         (tree (org-element-parse-buffer))
         (records
          (delq nil
                (org-element-map
                    tree 'link
                  (lambda (link)
                    (when (and (equal (org-element-property :type link) "file")
                               (not (org-element-property :search-option link)))
                      (let* ((path
                              (org-link-unescape
                               (org-element-property :path link)))
                             (file (expand-file-name path base)))
                        ;; URLエンコードされた空白なども試す。
                        (unless (file-exists-p file)
                          (setq file
                                (expand-file-name
                                 (url-unhex-string path)
                                 base)))
                        (list :begin (org-element-property :begin link)
                              :end (org-element-property :end link)
                              :raw (org-element-property :raw-link link)
                              :file file)))))))
         (sources
          (delete-dups
           (mapcar (lambda (record) (plist-get record :file))
                   records)))
         candidates
         errors
         (resized (make-hash-table :test 'equal))
         edits)

    ;; リンク先の画像を調べ、縮小が必要なものだけ候補にする。
    (dolist (file sources)
      (let ((ext (downcase (or (file-name-extension file) ""))))
        (when (and (file-regular-p file)
                   (not (file-remote-p file))
                   (member ext '("jpg" "jpeg" "png" "webp"))
                   ;; すでに生成した縮小コピーは再処理しない。
                   (not (string-match-p
                         "-web-[0-9]+\\'"
                         (file-name-sans-extension file))))
          (condition-case err
              (let* ((size
                      (snowfox/org2blog--dimensions file imagemagick))
                     (long-side (max (car size) (cdr size))))
                (when (> long-side snowfox/org2blog-image-max-dimension)
                  (push (list file size) candidates)))
            (error
             (push (format "%s: %s"
                           file
                           (error-message-string err))
                   errors))))))

    (setq candidates (nreverse candidates))

    (when candidates
      (unless
          (yes-or-no-p
           (format
            "%d枚の画像を縮小コピーにして、このバッファのリンクを差し替えますか? "
            (length candidates)))
        (user-error "処理を取り消しました"))

      ;; 元画像は残したまま、縮小コピーを作る。
      (dolist (candidate candidates)
        (let ((file (car candidate)))
          (condition-case err
              (puthash file
                       (snowfox/org2blog--resize-copy file imagemagick)
                       resized)
            (error
             (push (format "%s: %s"
                           file
                           (error-message-string err))
                   errors)))))

      ;; リンクの位置がずれないよう、後ろから順に差し替える。
      (dolist (record records)
        (let ((target (gethash (plist-get record :file) resized)))
          (when target
            (condition-case err
                (push (list (plist-get record :begin)
                            (plist-get record :end)
                            (snowfox/org2blog--rewritten-link
                             record target base))
                      edits)
              (error
               (push (error-message-string err)
                     errors))))))

      (dolist (edit (sort edits (lambda (a b) (> (car a) (car b)))))
        (goto-char (nth 0 edit))
        (delete-region (nth 0 edit) (nth 1 edit))
        (insert (nth 2 edit))))

    (dolist (error-message (nreverse errors))
      (message "画像処理: %s" error-message))

    (message "画像処理完了: 縮小コピー %d枚、リンク差し替え %dか所"
             (hash-table-count resized)
             (length edits))))

実験

2026-10-29_20-13-08_screenshot-web-500.png

画像の表現について

概要

Image-GS: Content-Adaptive Image Representation via 2D Gaussians (Zhang et al. 2025) という論文を見た。

Neural image representations have emerged as a promising approach for encoding and rendering visual data. Combined with learning-based workflows, they demonstrate impressive trade-offs between visual fidelity and memory footprint. Existing methods in this domain, however, often rely on fixed data structures that suboptimally allocate memory or compute-intensive implicit models, hindering their practicality for real-time graphics applications. Inspired by recent advancements in radiance field rendering, we introduce Image-GS, a content-adaptive image representation based on 2D Gaussians. Leveraging a custom differentiable renderer, Image-GS reconstructs images by adaptively allocating and progressively optimizing a group of anisotropic, colored 2D Gaussians. It achieves a favorable balance between visual fidelity and memory efficiency across a variety of stylized images frequently seen in graphics workflows, especially for those showing non-uniformly distributed features and in low-bitrate regimes. Moreover, it supports hardware-friendly rapid random access for real-time usage, requiring only 0.3K MACs to decode a pixel. Through error-guided progressive optimization, Image-GS naturally constructs a smooth level-of-detail hierarchy. We demonstrate its versatility with several applications, including texture compression, semantics-aware compression, and joint image

ニューラルイメージの表現は、視覚データをエンコードしてレンダリングするための有望なアプローチとして浮上しています。学習ベースのワークフローと組み合わせて、視覚的な忠実度とメモリフットプリントの間の印象的なトレードオフを示しています。ただし、このドメインの既存のメソッドは、多くの場合、メモリを最適に割り当てる固定データ構造や、リアルタイムグラフィックスアプリケーションの実用性を妨げている固定データ構造に依存しています。 Radianceフィールドレンダリングの最近の進歩に触発されて、2Dガウスに基づいたコンテンツに適した画像表現であるImage-GSを紹介します。カスタム微分可能なレンダラーを活用すると、画像GSは、異方性の色付きの2Dガウスのグループを適応的に割り当て、徐々に最適化することにより、画像を再構築します。特に、不均一に分散されている機能や低ビトレートレジームで頻繁に見られるさまざまな様式化された画像にわたって、視覚的な忠実度と記憶効率の間の好ましいバランスをとっています。さらに、リアルタイムの使用のためのハードウェアに優しい迅速なランダムアクセスをサポートし、ピクセルをデコードするのに0.3K Macのみが必要です。エラー誘導のプログレッシブ最適化を通じて、 Image-GSは自然に控えめなレベルの階層を自然に構築します。テクスチャ圧縮、セマンティクス認識圧縮、ジョイント画像など、いくつかのアプリケーションでその汎用性を示します

個人的な背景

随分前に画像検索を上記とは別の特徴抽出で行なった。画像の特徴量の抽出方法はいくつかあるが、この方法はレンダリングにも関わる方法である。微分レンダリングなどの技術にも興味を惹かれた。Alice’s Adventures in a Differentiable Wonderland – Volume I, A Tour of the Land | Abstract も併せて読みたい。

参考文献

Zhang, Yunxiang, Bingxuan Li, Alexandr Kuznetsov, Akshay Jindal, Stavros Diolatzis, Kenneth Chen, Anton Sochenov, Anton Kaplanyan, and Qi Sun. 2025. “Image-Gs: Content-Adaptive Image Representation via 2d Gaussians.” In Proceedings of the Special Interest Group on Computer Graphics and Interactive Techniques Conference Conference Papers, 1–11. Siggraph Conference Papers ’25. ACM. https://doi.org/10.1145/3721238.3730596.

超幾何関数について

概要

超幾何関数を理解するために計算を中心に記載してゆく。超幾何関数に必要な関数も計算してゆく。

\(\Gamma\) 関数

(薮下 1991) の最初にある以下の数式を計算する。

\[ \Gamma(z)=e^{-C z} \frac{1}{z \prod_{n=1}^{\infty}\left(1+\frac{z}{n}\right) e^{-z / n}} \]

import numpy as np
from scipy.special import gamma as sp_gamma

def my_gamma(z):
    C = 0.57721
    return np.exp(-C*z) / (z *np.cumprod([(1 + z/n)*np.exp(-z/n) for n in range(1, 1000)])[-1])

my_gamma(10.0), sp_gamma(10.0)

import matplotlib.pyplot as plt

x = np.linspace(1.0, 5.0, 10000)
plt.clf()
plt.plot(x, sp_gamma(x), label="scipy.special.gamma")
plt.plot(x, my_gamma(x), label="mine")
plt.legend()
plt.savefig(outfile)

outfile
qZ1E-8HX9ZsTI.png

参考文献

薮下 信. 1991. 特殊関数とその応用. 第6刷 ed. 森北出版. https://ci.nii.ac.jp/ncid/BN09363031.

title

概要

draw blue fish.

20250624192539_1024x1024_image.png
math_chart_in_thismonth_2025-01-03 19:34:03.351431.png

draw red fish.

20250624191501_1024x1024_image.png

Hyper realistic sci-fi rendering of super complicated technical machine.

20250623210721_1024x1024_image.png

参考文献

日誌 2025/03/29

記事

My Favorite C++ Pattern: X Macros ではC/C++言語のマクロの興味深い使い方が紹介されていた。宣言や初期化で重複する記述が繰替えす場合に適用するようだ。インクルードするファイルに関数のような構造(X())で展開したい情報を記述し、インクルードする方で使い捨てのマクロX()を定義してその中にファイルを展開する。

mre/idiomatic-rust: 🦀. では見本となるRustのプロジェクトなどを集めたガイドラインである。

学習の進捗

解析教程と関数解析を少し復習した。

解析教程は剰余付きTaylor公式の復習、関数解析は無限遠で消える連続関数のことについて。

TaskChute

数学

数学の実績時間(今週2025/03/23 – 2025/03/29; 0 days 12:23:00)
タスク名 実績時間
高瀬数学塾の復習 0 days 04:01:00
高瀬数学塾 0 days 02:24:00
解析教程の学習 0 days 02:12:00
関数解析の復習 0 days 02:03:00
書籍「ディリクレデデキント整数論講義 」 0 days 00:37:00
線型代数Gの復習 0 days 00:35:00
書籍:証明の読み方・考え方 0 days 00:31:00
数学の実績時間(今月; 3 days 01:39:00)
タスク名 実績時間
数学カフェ 0 days 15:15:00
数学工房 0 days 14:51:00
線型代数Gの復習 0 days 09:21:00
関数解析の復習 0 days 07:40:00
高瀬数学塾 0 days 07:09:00
高瀬数学塾の復習 0 days 05:20:00
書籍「素数が香り、形が聞こえる」 0 days 03:33:00
解析教程の学習 0 days 02:12:00
機械学習セミナー 0 days 02:10:00
書籍「ディリクレデデキント整数論講義 」 0 days 01:55:00
線形代数Gの復習 0 days 01:39:00
書籍「n月刊ラムダノートVol5No1」 0 days 00:47:00
書籍:証明の読み方・考え方 0 days 00:31:00
書籍「基礎から学ぶ量子計算」 0 days 00:25:00
線形代数の復習 0 days 00:25:00
書籍「数覚とはなにか?」 0 days 00:13:00
書籍「ガウスの数論世界をゆく」を読む 0 days 00:13:00
math_chart_in_thismonth_2025-03-29 20:01:11.987404.png

コンピュータ

コンピュータの実績時間(今週; 0 days 00:13:00)
タスク名 実績時間
書籍「Rustアトミック操作とロック」 0 days 00:11:00
org-publish/AWS 0 days 00:02:00
コンピュータの実績時間(今月; 0 days 06:36:00)
タスク名 実績時間
書籍「Rustアトミック操作とロック」 0 days 02:03:00
manjaro linuxのアップデート 0 days 01:33:00
書籍「ゼロから学ぶRust」 0 days 01:18:00
Gradioの練習 0 days 00:58:00
書籍「Let Over Lambda」を読む 0 days 00:37:00
org-publish/AWS 0 days 00:07:00

参考文献

日誌 2025/01/14

学習の進捗

関数解析は単調クラス定理まで進んだ。単調クラスは単調列の極限集合がそのクラスに属するというものである。

(ダグ and Hoyte 2009) はリードマクロの節を読み、CL-PPCRE に関するマクロの導入まで。

超幾何関数はデバッグにより処理を追った。 関数 acb_hypgeom_pfq_sum の実装と論文を対応させたい。

記事

Why I Chose Common Lisp — Dan’s Musings を読んだ。Common Lispの環境構築は未完成なので参考にして開発環境を整えたい。

Context-Generic Programming は Rust の新しいパラダイムのようだ。また時間を見て理解したい。

jfalcou/eve: Expressive Vector Engine – SIMD in C++ Goes Brrrr はC++で SIMDを書くときの参考になりそうだ。

B-Trees: More Than I Thought I’d Want to Know | Ben Congdon は B-Tree について書かれた記事である。

TaskChute

数学

数学の実績時間(今週2025/01/12 – 2025/01/18; 0 days 03:32:00)
タスク名 実績時間
関数解析の復習 0 days 01:47:00
解析教程の学習 0 days 01:20:00
書籍「ガウスの数論世界をゆく」を読む 0 days 00:25:00
数学の実績時間(今月; 0 days 21:35:00)
タスク名 実績時間
関数解析の復習 0 days 08:30:00
解析教程の学習 0 days 06:50:00
機械学習セミナー 0 days 02:20:00
超幾何関数の論文を読む 0 days 02:07:00
書籍「ガウスの数論世界をゆく」を読む 0 days 00:43:00
超幾何関数のメモまとめ 0 days 00:26:00
機械学習セミナーの勉強 0 days 00:20:00
位相群の予習 0 days 00:19:00
math_chart_in_thismonth_2025-01-14 21:27:31.169331.png

コンピュータ

コンピュータの実績時間(今週; 0 days 01:55:00)
タスク名 実績時間
超幾何関数の計算 0 days 01:09:00
書籍「Let Over Lambda」を読む 0 days 00:37:00
HackerNewsの閲覧 0 days 00:08:00
AWSにログインする 0 days 00:01:00
org-publishの実施 0 days 00:00:00
コンピュータの実績時間(今月; 0 days 12:04:00)
タスク名 実績時間
計量ツールの開発 0 days 03:26:00
Common Lispの書籍を読む 0 days 01:50:00
Rustのエディター作り 0 days 01:39:00
EmacsでのC言語開発環境の構築 0 days 01:19:00
超幾何関数の計算 0 days 01:09:00
書籍「Tidy First?」を読む 0 days 00:52:00
HackerNewsの閲覧 0 days 00:42:00
書籍「Let Over Lambda」を読む 0 days 00:37:00
ブログ環境の改善 0 days 00:13:00
ブログのテンプレートを作成 0 days 00:12:00
AWSにログインする 0 days 00:05:00
org-publishの実施 0 days 00:00:00
コーディング 0 days 00:00:00

参考文献

ダグ ホイト, and Doug Hoyte. 2009. Let over Lambda Edition1.0. Translated by タイムインターメディアHOPプロジェクト. 単行本. エスアイビー・アクセス. https://lead.to/amazon/jp/?op=bt&la=ja&key=4434133632.

日誌 2025/01/08

学習の進捗

関数解析は直積測度を学んだ。切断など。

書籍「Tidy First?」(Beck 2024) を読んだ。何年もプログラマーをやっていて実践してきたことも多いが、肝に銘じてコーディングしたい。

書籍 「LET OVER LAMBDA Edition1.0」 (ダグ and Hoyte 2009) を読んだ。 gensymが出てきてマクロの深層に迫っていく。

TaskChute

数学

数学の実績時間(今週2025/01/05 – 2025/01/11; 0 days 06:23:00)
タスク名 実績時間
関数解析の復習 0 days 02:59:00
解析教程の学習 0 days 02:18:00
超幾何関数の論文を読む 0 days 00:40:00
超幾何関数のメモまとめ 0 days 00:26:00
数学の実績時間(今月; 0 days 14:25:00)
タスク名 実績時間
関数解析の復習 0 days 06:00:00
解析教程の学習 0 days 05:30:00
超幾何関数の論文を読む 0 days 01:50:00
超幾何関数のメモまとめ 0 days 00:26:00
機械学習セミナーの勉強 0 days 00:20:00
位相群の予習 0 days 00:19:00
math_chart_in_thismonth_2025-01-08 20:22:48.368672.png

コンピュータ

コンピュータの実績時間(今週; 0 days 02:47:00)
タスク名 実績時間
Common Lispの書籍を読む 0 days 00:58:00
Rustのエディター作り 0 days 00:35:00
EmacsでのC言語開発環境の構築 0 days 00:27:00
書籍「Tidy First?」を読む 0 days 00:24:00
ブログのテンプレートを作成 0 days 00:12:00
HackerNewsの閲覧 0 days 00:10:00
AWSにログインする 0 days 00:01:00
org-publishの実施 0 days 00:00:00
コンピュータの実績時間(今月; 0 days 09:23:00)
タスク名 実績時間
計量ツールの開発 0 days 03:26:00
Common Lispの書籍を読む 0 days 01:50:00
Rustのエディター作り 0 days 01:39:00
EmacsでのC言語開発環境の構築 0 days 01:19:00
HackerNewsの閲覧 0 days 00:29:00
書籍「Tidy First?」を読む 0 days 00:24:00
ブログのテンプレートを作成 0 days 00:12:00
AWSにログインする 0 days 00:04:00
org-publishの実施 0 days 00:00:00

参考文献

Beck, Kent. 2024. Tidy First? ー個人で実践する経験主義的ソフトウェア設計. Translated by 吉羽 龍太郎, 永瀬 美穂, and 細澤 あゆみ. 単行本(ソフトカバー). オライリー・ジャパン. https://lead.to/amazon/jp/?op=bt&la=ja&key=4814400918.
ダグ ホイト, and Doug Hoyte. 2009. Let over Lambda Edition1.0. Translated by タイムインターメディアHOPプロジェクト. 単行本. エスアイビー・アクセス. https://lead.to/amazon/jp/?op=bt&la=ja&key=4434133632.

日誌 2025/01/07

学習の進捗

関数解析は完備測度まで完了し、つぎに直積測度となる。

解析教程は一様収束などがでてきた。C1級関数の定義がつづく。

超幾何関数の調査は flintlib/flint: FLINT (Fast Library for Number Theory) の実行環境を整え、デバッグが可能にした。

ONNXモデルのマージも少ししらべた。

TaskChute

数学

数学の実績時間(今週2025/01/05 – 2025/01/11; 0 days 05:38:00)
タスク名 実績時間
解析教程の学習 0 days 02:18:00
関数解析の復習 0 days 02:14:00
超幾何関数の論文を読む 0 days 00:40:00
超幾何関数のメモまとめ 0 days 00:26:00
数学の実績時間(今月; 0 days 13:40:00)
タスク名 実績時間
解析教程の学習 0 days 05:30:00
関数解析の復習 0 days 05:15:00
超幾何関数の論文を読む 0 days 01:50:00
超幾何関数のメモまとめ 0 days 00:26:00
機械学習セミナーの勉強 0 days 00:20:00
位相群の予習 0 days 00:19:00
math_chart_in_thismonth_2025-01-07 20:55:37.657452.png

コンピュータ

コンピュータの実績時間(今週; 0 days 01:53:00)
タスク名 実績時間
Common Lispの書籍を読む 0 days 00:42:00
EmacsでのC言語開発環境の構築 0 days 00:27:00
Rustのエディター作り 0 days 00:24:00
ブログのテンプレートを作成 0 days 00:12:00
HackerNewsの閲覧 0 days 00:07:00
AWSにログインする 0 days 00:01:00
org-publishの実施 0 days 00:00:00
コンピュータの実績時間(今月; 0 days 08:29:00)
タスク名 実績時間
計量ツールの開発 0 days 03:26:00
Common Lispの書籍を読む 0 days 01:34:00
Rustのエディター作り 0 days 01:28:00
EmacsでのC言語開発環境の構築 0 days 01:19:00
HackerNewsの閲覧 0 days 00:26:00
ブログのテンプレートを作成 0 days 00:12:00
AWSにログインする 0 days 00:04:00
org-publishの実施 0 days 00:00:00

参考文献