月別アーカイブ: 2025年10月

純粋に992mを僕は登る

9月末、連続5日間の休暇が取れる・・・ そう知った僕は、きみに会いに行く決心をした。
そう、40 年前に、きみと見た なつかしい風景に、会いたくて。

今、どうしても・・・ 会いたくて。

太平洋側の海岸沿いの街からクルマで5時間30分
きみは輝ける空の下、碧く、静かに佇んでた。


関越トンネルを抜けて見た越後湯沢の風景は、土砂降りの二乗くらいの雨の中に霞んでた。
フルワイパーにしても、前なんか、まるで見えない。

幸い、平日で交通量が少なかったので減速し、安心して走れる速度をキープする。
後続車がいたらビビリな僕は、無理しても速度を維持しただろうけれど。

バックミラーにも、ドアミラーにも、後続車は写らない。

( よかった・・・ )

長岡へ近づくに連れ、雲は高くなり、所々に切れ間も見えた。
左手側の北陸道方面の空は、さらに明るい。

40 年前に後にして以来、3日間といたことのない場所。
そこを「ふるさと」と呼ぶ資格なんて、僕にはあるのだろうか・・・

母さん・・・

ずっと、心配ばかりかけた、けど・・・
ごめんね。

僕は、どうしても、あの頂に立ちたいんだ。
理由は言葉にしなくても、母さんは知ってるはずさ。

言い出したらきかない子だから・・・って、
いつも、そう言って、でもいちばんに、僕を信じてくれた、母さん。

もし、そこに「リアルな」 プーさん がいても・・・
僕は、頑張って、逃げる、から。

必ず、元気で、帰るからね。
母さん・・・

スタートは海抜0m

きみに再び登ると、そう、決心した時から僕は決めていたんだ。
スタートは、海抜0m。

それだけは、絶対に譲れない。

日本海の「水」に触れて、そこから垂直方向へ 992 m、
水平方向での移動距離は概算 6.7km くらいか?

そこに、君の頂きがある。

2025年10月3日、午前6時。

「きをつけていきなせ」

母さんは、いつも通りの笑顔と、言葉で、僕を送り出してくれた。

僕的な予定では、きみの頂きにあるはずの避難小屋に泊まって、
ふるさとの街の夜景を、じっくり見たかったのだけれど、
母さんの顔を見たら、さすがにそれは言い出せなかった。

僕のいちばんの目的は、きみの頂きに立つこと。
ふるさとの街の夜景を見るのは、その先の未来でもかまわない。

だから、僕は母さんに約束した。
米山駅発16時48分の電車に乗って、必ず、帰るからね。と・・・

海岸通りの無料駐車場にクルマを停めた。

きみに少しだけ、近づけた。


時刻は午前6時15分。柏崎駅までここから1kmちょっと。
歩いて駅へ。

真水は 1.5 L ザックに用意したけれど、それとは別にペットボトル飲料を何本か持ちたい。
駐車場から駅までにコンビニか、自販機があるだろう・・・そう思いつつ歩くが、それがない。

どうしようかと悩みつつ、駅に到着してしまった。

駅に、コンビニがあった! よかった!! たすかった!!!


駅のコンビニで、おにぎり1個と、ペットボトル飲料を購入。
兼非常用食料として太平洋側から持参した「乾きもの」系のごく軽量な食べ物と合わせて2日分。
これで日帰り予定の食料に心配はない。

米山駅までの切符を購入。運賃は 240 円。
米山駅は無人駅と聞いたので現金を券売機に投入する。

Suica にチャージしたお金があっても、僕のふるさとでは、それはまだ忘れるべきことのようだ。

券売機を前にして、たまらなく、うれしい 気持ちがしたのは、なぜだろう・・・

駅からは、なぜか、小さく、きみが見えた


普段使いではない、登山用に愛用している時計を、見る。

発車まで、あと3分と少し。


40 年前、おそらく、これに近い時間。
僕は、この駅から、同じように、この電車に乗車した・・・ はずだ。

なつかしい、ともだち といっしょに。

でも、なぜ、だろう。
どうしても、その時のことを、思い出せない。

なぜ、なんだろう・・・

あぁ 電車が、動き、始めた・・・

鯨波、青海川、笠島・・・ なつかしい駅名をアナウンスする声が聞こえる。
車掌さん、乗車中のみなさんにとっての日常は、今日の僕にとっては特別な時間だ。

ただ、特別な時間でありながら、米山駅の風景を、僕はどうしても思い出せなかった。

駅の風景すら、思い出せないままの僕を乗せて・・・
やがて電車は、記憶にない、でも、なつかしいはずの駅へ 着いた。

午前7時12分。米山駅到着。降車したのは、僕ひとり・・・だった。


きみの真横(西側)?へ来た。
かすかに、きみの横顔が見えた。

逆光だ。薄雲(高層雲?)に隠れてはいるが、太陽が眩しい。


山を登りに来た。それは、間違いのない事実だが。

でも、僕は、海を目指す。
スタートは、海抜0m。
そう、決めて いた から。

振り返れば、波 静かな・・・ ふるさとの海が・・・

夏の海の思い出は、必ず夕陽で終わってる。
水平線の向こうに沈む太陽を、僕は何度、数えたかな・・・


感傷に浸りながら、左右を見回して、海への道を探す。
もとより僕は、米山駅付近の海岸へ通じる道を知らない。

( ほぼ海岸にある駅だ。海なんて、すぐ、行けるだろう・・・ )

そう思っていた自分の考えの甘さにすぐ気づき、取りあえず、唖然とする。

( 海岸線に沿って線路があるってコトは、踏切を渡らないと、海へは 絶対に行けない!)

でも、米山駅の左右、どっちを見ても、見渡す限り、およそ踏切なんて、『 ない!』

叢に一箇所、「強行突破用の小径?」に見える「何モノかの踏み分け跡」があったが。

もちろん、そんなところは、通れても、通れない。

現在時刻は7時30分。

登山口のある大平集落までは、米山駅から約 4.2 km。徒歩で約1時間。
午前9時に登山を開始するなら、あと 30 分以内に大平へ向かわねばならない。

復路を思うと、ここから海まで、行って 15 分がリミット。

海に向かって考える。右か、左か。

わからん。

でも、人家は海に向かって右側の方が、圧倒的に多そうだ。
ってコトは、僕の実家もそうだけど、人々の生活は海に密着してるはずだから、
海に向かって右側の集落のどこかに、海岸の砂浜へ通じる道が「必ず」ある、はず。

そう信じて、駅から海に向かって右手側の集落へと続く国道8号線沿いの道をひたすら歩く。
5分もしないうちに汗が流れ落ちる。

なんでだ? 着てるのは F社製の速乾 Tシャツ1枚だけだぞ。

今日は10月3日、まだ午前7時30分、秋分はもう10日も前に過ぎただろ?
どうして、こんなに暑いんだ?

記憶は時を駆けて・・・ 遠い 過去へ

でも、あの時も暑かったよな・・・

やっぱり、40年前の4月1日、僕はオンボロのチャリンコに乗って・・・
この道を・・・国道8号線を、京都へ、その先へ
延べ 1000 km の道を 夢中で駆ける旅に出たんだ・・・

若かった 夢のせいかも しれないけれど。
あの時も、僕は冷たい風の中、汗が流れるのを感じてた・・・

そう思った途端、時は過去から現在に舞い戻る。
そうだ。40 年経っても、僕は、何にも・・・ 変わって ない じゃないか・・・

うん、やっぱり僕は、僕でしか、ない んだ。
歩き方は、変わらない。

違う。変えられないんだ。
歩き方も・・・ 何もかも、全部。
僕は・・・初めから、僕で、最後まで、僕でいるしか、ない から。

それを確かめたくて、今日、ここに来た。
ちがうかい?

そう思いつつ、きっと、あるはずの標識を探す。
それは・・・

『 米山海水浴場 → 』

あった! この表示を待ってたんだ。
重いザックを背負って、気持ちだけは駆けるように急ぐ。

見えた。集落の外れで、道が「線路の上を越してる!」
集落の外れは「海食崖」で、トンネルがあり、その手前で、
道はトンネルの上を越して、小さな海水浴場へと続いていた・・・

正真正銘 海抜0mだ。


法的な基準は違っていても構わない。
僕の海抜0mは、ここなんだ。

どうしても、ここから、始めたかったんだ。
きみへの旅の始点。

それが、ここさ。

生涯、忘れない瞬間。


僕は、きみの頂きへ、行く。
きみは、おそらく、誰をも待たず、また、誰をも追わないだろう。

でも、人は、誰かを待ち、誰かを追い、時にはそれに疲れ、俯いて、
そして、僕のように、きみの頂きを目指すこともあるだろう。

僕は、知っている。
きみは、黙して、何も言わない。

救いなど、ない のだ。

きみも、知っている。
救いなど、ない ことを。

ならば、きみの頂で
せめて 共有しようじゃないか。

きみが 1500 万年間 見てきたであろう 風景 を・・・

大平への道

大平へ Go!


予想以上に時間をロスしたが、大平登山口午前9時の予定には何とか間に合いそうだ。
ただ、ここから大平までの道が皆目わからない。
道は覚えていないが、Google Map という、40 年前にはなかった Secret Weapon も、今はある。
それに頼らなくても、米山駅の近くには、大平登山口への道を案内する標識があった。

あそこまで戻れば、なんとかなる、はずだ。

あった。こっちだ。


かつて、ここを歩いたことは、もちろん記憶にない。が、40 年前、8号線も、北陸道も、すでに存在していたのは間違いない事実。ただ、なんとなくあの頃は、国道8号線を横断していたような・・・ かすかな記憶があるような気がするが、それは思い違いか・・・?

案内標識の矢印方向を見ると・・・

( ガード下なんて、通ったか? )
記憶にない風景には、やはり違和感を感じてしまう・・・


迷っている場合ではない。
9時までには大平登山口へ行かねばならない。案内標識を信じてガード下をくぐる。

その先に見えた道は・・・

いつか、歩いたはずの道。


ここを、何度、歩いたんだろう。
少なくとも何往復かはしていると思うのだが、断片的な記憶しかない。
はっきり、覚えているのは、正直1度、それも往路だけだ。

あの時、歩きながらチーズの話をしてくれた人は、確か、高校の体育の先生だったはずだ。
お名前も、お顔も、もう、思い出せないが・・・ 確か、黒縁の眼鏡をかけていたような・・・

唯一、間違いないと思えるのは、年齢だ。
あの時、先生は、今の僕とそう変わらない年齢だったんじゃないか?

いや、もっと、若かったかもしれない。
僕の思い込みも、多分にありそうだからな・・・

今でも、お元気でいらっしゃるだろうか・・・

その想いをきっかけに、まるで、泉が湧き出だすように、僕の中に記憶がよみがえる・・・

そうだ、思い出した。高校2年の2月10日も、僕はここを歩いたはずだ。
あいつとふたりで頂きを目指した日、僕は間違いなくこの道を歩いている。

雪庇とクレバスと、吹雪の中、やっとたどり着いた雪に埋もれた山頂の避難小屋、
寒かった吹雪の夜、朝、強風の中でバリバリに凍った手袋等の断片的な記憶。
その中に下山後の復路の起点、大平付近?と思しき風景が残っている。
記憶は断片的でも、あの時、米山駅-大平間を歩いて往復したのは間違いない事実だ。

だから、記憶に残る回数で言えば、僕がこの道を歩くのは3回目ということか。

実際には、何度、歩いたのだろう・・・ その数倍はあると思うのだが。
確かめる術もなく、今さら、確かめたところで何かがよみがえるわけでもないが・・・

40 年の歳月は、こんなにも過去を風化させてしまうものなのか。
あらためて、過ぎ去った日々の事どもを思う。

あぁ・・・ また、山頂が見える・・・


山頂方向には、うすい雲があるが、海側はよく晴れている。
予報では、今日は上空に薄雲の広がりやすい晴れだと言っていたが、雲はどちらへ動く?

振り返れば・・・、ずいぶんと遠く、下の方に海が見える。
もう 100m くらい登ったかな?

クルマが3台くらい登って行ったが、道行く人はいない。


時計で高度を確認。
当てになるような、ならないような・・・

高度は、109 m


まだ、大平へ着かない。
少し、遅れている?

トレッキングポールにぶら下げた『クマよけの鈴』の音が盛大に響く。

母さん、ごめんね。
でも、心から、ありがとう。


だんだん、明るくなってきた。


時間的には、もう大平へ到着してもいい頃だ。
そう思いつつ、コーナーを曲がると・・・ 何軒か、家屋が見えた。

着いた! ここが大平だ。


時刻は、午前 9 時 7 分 58 秒、予定より若干遅れている。

高度は210m、残り あと 800m。


ここで、想像もしていなかったモノを発見!

なんと、自動販売機が設置されていた!


自販機の脇には・・・

「飲めません」とのことなので、水の冷たさだけ確かめさせていただきました。


2025年 10 月現在、大平の米山登山口駐車場は改修工事中で使用できないという事前に得ていた情報の通り、上の画像のすぐ右側では重機を入れての工事が進められていました。ヒザまで泥に浸かって、作業している皆さんに頭を下げて先へ進みます・・・

ちなみに道は、ほとんど枯れ木に覆われてるが、舗装されてる・・・


この「舗装されてる道」、記憶にあるカモ!
そう感じつつ、先へ進むと、

どうかホンモノに会いませんように・・・。ただ、ただ、祈りつつ、通過。


こんな感じの斜面の小径を、ちょっと登ったら、また道幅の広い林道に出て

クマは、いません。が、そのかわりに・・・


案内標識があった!

ここから山頂まで 2.30 時間とある。
2時間30分という意味なのだろう。

そうだ。なんとなく・・・ ここは覚えてる!
左へ行けば林道。標識の右側(写真では正面)の小径が登山道だ。

昨日の激しかった雷雨の名残りか、道はかなりぬかるんでいるようだ。
今日行くのは、木の根っこと、泥んこの道?

森林限界より上の世界が好きな僕は、ちょっとため息。
でも、それは想定内。

林道の方が歩きやすい? のかもしれないが、ここはもちろん「登山道」方向へ。

なんせ 40 年振りの道。この先のことを考え、念のため地図も確認。

20 mくらい? ずれてるようだ。

「偏差値 25 m」とあるから、誤差の範囲内なのだろう。
大丈夫。これならひとりでも道に迷うことはなさそうだ。

行くぞ!

輝かな 風景

いつものトレッキングポールに助けてもらい、一歩一歩、確実に大地を踏みしめて登って行く。
おぼろげながらも記憶にある通り、やはり、この山の登りはきつい。

実際、平均しての傾斜角はどれくらいになるのだろう?

今日は、純粋に海水に触れてからスタートしているから、登りの標高差は米山の高さそのもの、最新のデータでは 992.5 m だ。で、水平方向の移動距離は、出発地点の米山海岸から米山山頂まで、3500 ~ 4000 m 程度のようだ(米山海岸は、おおよそ北緯 37.32 度、東経 138.52 度付近、米山山頂は、北緯 37.2895 度、東経 138.4839 度。地図上で両地点を結ぶ直線を測定すると、約 3.7 km前後の水平距離になる。実際には、斜面を登るために移動距離はより長くなり、登山ルート全体では約 5.5 〜 6.0 kmほどか?)。これを元に平均傾斜角を求めると、14 ~ 15.8 度くらいになる。これは登山道や坂道として快適な歩行の限界とされる 6 ~ 10 度をはるかに上回る値だ。

てか、計算するまでもなく、この登攀は、当たり前に、苦しい。それが、真実。
トレッキングポールなしでは、到底、僕には登れない。

はぁ はぁ はぁ

ふと気づけば、登山道一面に大量の栗が落ちている・・・

もしかして、ここは、クマの餌場?


あわわ・・・

必死で歩く速度を上げようとするが、足が前に出ない。
恐怖心もあるが、登りが急傾斜すぎて、既に、体力の限界なのだ。
それでも、よろめくように、必死に前に出る。

今にも藪からクマが栗を、いや僕を、食べに現れそうな気がして、たまらない気持ちになる。
しかし、登りが・・・ 僕には急すぎる・・・ これ以上は、マジ、ムリ。

はぁ はぁ はぁ きつーい。

心臓が口から飛び出しそうだ。

やばい。こんなハイペースでは絶対に参ってしまう。

少し、休まなければ・・・

そう思って、振り返ったら・・・

北陸道の高架橋(右)の先が、米山海岸だ・・・
あそこから、来たんだ・・・


心象風景と、現実風景のあまりの違いに、

心象風景のクマのことは忘れ、我に返って、しばし、現実の風景を見つめる。

さっきまで、あそこにいたんだよなー

なのに、もう、ここまでこれた。

あと残り、2/3くらいかな?

タオルはもう、吸水力の限界。でも、替えのタオルは持ってこなかった。大失敗。

ザックのハーネスに付けたペットボトル飲料の残りも、あとほんの少ししかない・・・

( 大平の自販機で2本買ってきてほんとによかった! ただ、むちゃ、重たいケド )

そう思いつつ、ペットボトルに残った飲料を心置きなく飲み干して、替えのボトルをザックのポケットから出し、空になったボトルと交換する。これでペットボトル飲料は残りあと3本、水は昼食用に 500 mL、予備の水筒に1L残っている。ここまで発汗がすごいと、飲料水は、その重さより、やはり量が優先する。もちろん、山頂から 15 分ほど下ったところに水場があることは今でも記憶にある。が、たとえ、それを覚えていても、今、ここにある水が愛しい。ヒトには水に対する言葉にできない欲求があることを、僕は山に来るたびに感じてしまう。

( そうだ。熱中症対策もしておこう・・・ )

持参した・・・ と言うか、正確には、前回の山行の残りの塩あめをザックのポケットから取り出して、口に含み塩分もチャージする。ここで熱中症になったら助けてくれる人は誰もいない。クマの件も含めて、ここでのことはすべて「自己責任」。それがきみと僕との絶対に守らねばならない約束だ。

それにしても、発汗がひどい。夏の山行以来、運動していなかったこともあるが、この時期にしては気温が高すぎるんじゃないか?

このすぐ先、標高 650 m 付近に「二ノ字」という少し開けた場所があったはずだ。

そこで少し長めに休憩しよう。

そう思いつつ、登山道を 見上げる・・・

そう、『見上げ』る。

なんだか、おかしな表現だが、この場合、そう表現するのが最適なのだ。

40 年前は、このような階段は、なかった気がする・・・
作って下さった方に、心から感謝。


階段を上る際、通常は右足と左足を交互に前に出す。でも、ここではそれが出来ない。階段一段分の幅が広いこともあるが、それより何より、かなりの急登による疲労の蓄積のためだ。ヒザはガクガク、大腿はヒクヒク、どちらにも「ちから」というものが感じられない。基礎体力の衰えををあらためて実感。

毎日、ウォーキングしていた頃のふくらはぎのハリが、今はない・・・

( 仕事でも登らなければならないんだ。運動しなきゃ! )

ただ・・・ その思いを、今、暮らしている街まで、持ち帰れるか・どうか、それが問題だ。

そんなとりとめもないことを思いつつ、整備された階段を上り続ける。

はぁ はぁ はぁ 太腿の筋肉が限界だ。

「二ノ字」は・・・ まだか?

一歩、足を踏み出す度に、その思いだけを噛みしめる・・・

何度、何回、その思いを繰り返した ことか。

フッと視界が開けたと思ったら、そこが「二ノ字」だった。

かつてここが「二つの集落=字(あざ)」の境界だったので「「二ノ字」と呼ばれるようになったとのこと。

米山(米山駅から往復)
URL:https://www.yamareco.com/modules/yamareco/detail-719251.html より引用

ここの標高は、約 650 m 。
山頂が 992.5 m なので、およそ全体の 2/3 を登ったことになる。

ここからは、きみの てっぺん が見えた。
手をのばせば届きそうとは言わないが、もうすぐそこだ。

きみは、輝ける空の下で


きみの てっぺん を見つめて呼吸すること、しばし。

さっきまで、肩で息をしていたことがウソのよう・・・

きみに、本気で会いたくなった 時から

こんな きみの姿に、会えると ずっと 信じてたんだ・・・

僕は、なぜ、きみに会いたくなったんだろう・・・

僕は、どうして、ここへ、来たんだろう・・・

きみの てっぺん に向かったまま、僕自身に、問いかける・・・

きみを見つめている 僕は・・・

40 年前の僕と・・・ どれほど変わったのだろう?

きみは、変わってなかった ね。

うん。僕も 変われなかったんだ。

それを、確かめに、ここへ 来た。

変わらないきみに会えたら、決して変わらないものもあるんだと・・・

もしかしたら、そう思えるんじゃないかって、僕は思ったのかもしれない。

僕の周囲では、瞬く間に変わってしまうことの方が、あまりにも 多すぎた・・・ から。

では、変わらなかった もの って、何?

それを、きみに、問いたくて。

そして、分かち 合いたく て・・・

「二ノ字」の真ん中にある岩に預けていた僕のザックのハーネスを握る。汗を吸い込んだハーネスは風に吹かれて驚くほど冷たい。日帰りなので、それほど重たいわけではないが・・・ この冷たさは格別だ。

うん。じゅうぶん、休息した。

歩く気力がよみがえってきた。

ザックの左ハーネスを左手で持ち上げ、僕の左肩に通して体を時計回りに回転させる。
続けて右手をザックの右ハーネスに通し、軽くジャンプしてザックのフィット感を確かめる。

見上げれば、きみと同じく、僕も・・・

今、輝かな空の下。

陽の当らないところを歩むことが多い僕には、もったいないくらいの明るさだ。

711米峰

今までの急登がウソのよう。


あぁ もしかして、あの場所は・・・

12 歳の時に見た、生涯、忘れないであろう風景が見えた場所?

はるかに妙高山(2,454m)火打山(2,462m)と焼山(2,400m)を望む


間違いない。きっと、ここだ。

12 歳だった僕は、あの日、ここから妙高山と火打山と焼山を見た。

そして、その向こう側には、さらに高く、真白な雪を被った北アルプスの山々が見えたんだ。

きみより高い山を見たことがなかった僕にとって、きみの向こう側に、きみより高い山があることは想像を絶する驚きだった。

純粋に、憧れた。

登ってみたいと、心から思った。

そうだ。あの日、息をのんで、見つめていた 風景だ。

新潟県柏崎市周辺では、12歳(小学校高学年)になると、地域の大人とともに米山に登るという風習がかつてあった。
登山を通じて自然の厳しさや美しさを体験し、地域の信仰や歴史に触れる良い機会でもあったようだ。

やがて、高校生になった僕は、これが原体験となって、迷うことなく山岳部へ入部した。

今、ここは「711米峰」と呼ばれているようだ。


その名前からわかる通り、ここの標高は 711 m

だいたい、あっている。


米山海岸で高度 0 mに設定した高度計の示度は、真の標高より 16 mほど低い。これは、上空にあった薄雲がとれてきた(=気圧が上がり、天候が良くなった)ためか?

地形図は、ここから先はしばらくハイキングコースのような道が続くことを示している。

でも、確かこのあたりに、急勾配の斜面をトラバースする、ちょっと危険な場所があった・・・はずだ。

traverse(横断する、横切る):登山で使われる場合は、「急斜面や崖のような場所で、上下ではなく横方向に移動すること」を意味する。

あの急斜面は、どこだろう?

ブナ林とガンバレ岩

山頂が、さらに近くに。
もう、避難小屋がはっきり見える。

711米峰を過ぎてからは、ハイキングコースとまでは行かないけれど、少し下るような場所もあって、中盤、中休み的な道を進む。しかし、稜線の上のような両側が切り立った崖になっている箇所もあり、体力的には楽でも、気は抜けない。万一、滑落したら、助けてくれる人はいないのだ。携帯電話の電波も先ほど調べたら、僕のは圏外だった。

( 集中! 集中!! )

しばし、慎重に進むと見えてきたのは・・・

あぁ ブナ林だ・・・

きみたちも、変わらないな・・・


高度 700 m から 800 m 付近にかけて、見事なブナ林が広がっているのも昔のままだ。

あのころは、ブナの根を掴んでよじのぼっていたような記憶もあるのだが・・・

傾斜もまたきつくなってきた。肩で息をしながら、ブナ林を上へ、上へ、進む。

そして、またひとつ、なつかしいものに出会えた・・・

あぁ ガンバレ岩だ!

誰が最初に描いたんだろう


昔は、こんなに、くっきり・はっきり 描かれていなかった・・・? ような覚えがあるし、手前にはハシゴはまだなくて、木の根っこを掴んで、服をドロで汚しながら這い上がった?ような気がするのだが、気のせいだろうか・・・

ちょっと待って・・・ 

急斜面のトラバースはどこへ行った?

たしか、ガンバレ岩の手前だった気がするが・・・

もしかして、危ないから、ルートが変更されたんだろうか・・・

もし、そうだとしてもまったく気づかなかった!

・・・ってか、さっき稜線みたいだなって思いながら通過したところがあったけど、両側が切り立った崖のように感じたぞ。むかしはあんな場所はなかった気がする・・・。もしかして、あれが新しいルートだったのかな?

尸羅場? 高校生だった当時の記憶にはない場所だ。

なんと読むのだろう? そして、なにをした場所なんだろう?

尸羅場は「しらば」と読むようだ。


木の枝に付けられた表示によれば、尸羅場とは「ここより先は女人禁制(女性の登山禁止)とされていたかつての結界」なのだそうだ。奥にはお地蔵さんもいらっしゃっる・・・ かつて、ここまで、大切に、大切に担ぎ上げた方がいたのだ。この事実ひとつを見ても、昔の人々の山への思い(信仰)が伝わってくる。一礼して通過する。

水場

40年前、登山で水を運ぶ(入れる)モノと言えば、間違いなくそれは「ポリタンク」だった気がする。正確には、本体がポリエチレン(PE)製でキャップがポリプロピレン(PP)製の水容器だが・・・ 特に多く使われたのは耐衝撃性・耐薬品性に優れる高密度ポリエチレン(HDPE)で、今思えば、なんとも言えない、鼻につく匂いがした。

元より、高校時代の僕は、そんな匂いなど気にするわけもなく、注ぎ口付きのポリタンクこそ、山岳部の必需品と信じて疑うことすらなかった。もちろん、匂いはそのまま山旅の記憶になった。

PET 素材やポリカーボネート製の水容器が主流となった現代では、「水容器素材の匂い」など考えられないことなのかもしれないが、当時は匂いはしても「水容器」=「ポリタンク」であったのだ。

そのポリタンクを抱えて、山頂と往復したのが、この「水場」だった・・・。

高校時代の僕は「装備」担当で、山での調理・給食を担当する「食糧:エッセン(なんでドイツ語を使っていたのか、当時も、もちろん今も、よくわからない)」係ではなかったが、それでもみんなのポリタンクを集めて、この水場へ、水汲みに来たことがあったように思う。

それが、山頂まで時間にして 15 分ほどの・・・ ここだった。

当時の案内表示は、明らかに違うはずだが、その風景を思い出せるわけもなく・・・


水場まで、下りてみたい気持ちがしなかったと言えば、それはウソになる・・・、が。

クマも喉が渇いたら、水を飲むだろうし、もちろん、山の中では水探しも一苦労だろうし、ならば、いつも水にありつけるヒトの水場を覚えて利用することもあるかもだし(実際あるそうです)、そうなると水場は、クマさんと鉢合わせする可能性「大」なりで・・・、とにかく、クマだけには会いたくない・・・

それに今、飲み切れないほど、水、持ってるし・・・

水場へ続く道


しばし、休憩を兼ねて水場へ続く道を眺め、水場行きは断念。ここは、登頂を優先することに。

時刻は 11 時 48 分、目標に設定した 12 時が迫ってきた。

727 / 722 m ???


711米峰を越えてからは、久しぶりの運動に多少は身体が慣れたのか、登り始めほどの苦しさは感じなくなった。それでも、汗水たらす状況に変わりはないが、足はしっかり前に出る。

あえて回転加工せず、現地での見た目を優先して掲載しました。


山頂まであと「5分」の案内石もあった。最初に見た時は、脳が文字の縦横変換に失敗し、「意味不明」であったが、横を通過する際に、意味をようやく理解。

正直、ここから先は、もう、無我夢中・・・

忘れたいことを、全部、忘れて。

なぜ、僕は、ここへ、来たのか?

なぜ、僕は、ここへ来たいと思ったのか?

なぜ、僕は、ここへ、来なければならなかったのか?

いちばん 考えたくない

生きている理由のようなもの すら

忘れて。

はぁ はぁ はぁ

いちばん そらに ちかい ばしょ へ

ぼくは ゆくんだ。

あぁ 40年を経て拝む 薬師如来さま。

薬師如来さまの背後には・・・

変わらない ふるさと の まち が 見えた。

風の音が聴こえる・・・

僕は、あまりにも有名な、ある会話を、思い出した。

登山家ジョージ・マロリーは、1923年3月18日付の ニューヨーク・タイムズ のインタビューで、記者から発せられたこの問いに対し、次のように答えたという。

George Mallory, 1923

うん。Malloryさん、

僕も こころから そう 思えた。

マウスカーソルの形状も含めてデスクトップ画面をキャプチャしたくなりました!みたいな時は、もしかしたら『コレ』が使えるカモ?しれません・・・②

“Say Hello to Capity Plus.” A Lightweight screen capture utility

上の図のように、マウスカーソルの形状も含めてキャプチャできます!
範囲の選択には、矩形に加え、正方形/楕円/正円も使えるようになりました!


画像編集に際し、自分が欲しいと思う必要最低限の機能のみを実装したプログラムを前回アップロードし、その紹介記事で次のように書きましたが・・・

『このアプリは本格的な画像編集に使用するための素材、もしくは、操作方法の解説を作成するために必要な情報画像(部分的な切り抜き画像)を簡単に作成したいという目的を実現するために開発しました。ですので「現在、表示されている画面の全部、もしくは一部を、必要であればマウスカーソルの形状を含めた画像データとして取得する」ことしかできません。保存した画像データを再度読み込んで表示したり、キャプチャした画像を加工する(例えば、ぼかす・モザイクをかけるといったような)機能はありません。ただし、画像の指定範囲を「ぼかす・モザイクをかける」機能は、後日、追加できたら、追加したいと考えています。』

今回、「ぼかす・モザイクをかける」といった機能に加え、既存の画像ファイルを読み込んで表示したり、アルファチャンネルを用いた透明化処理を PNG 形式の画像処理に追加するといった、自分では使わないかな? と思う機能も搭載した新しいバージョンができましたので紹介させていただきます。

【もくじ】

0.基本的な使い方と名称について(前回の記事 Plus α)
(1)起動方法
(2)キャプチャ方法
(3)操作パネルの位置の変更
(4)ラバーバンド形状
(5)処理一覧
 ・名称について
1.追加機能①「開く」
2.追加機能②「円形選択と保存・送信を可能に」
3.追加機能③「ぼかし処理」
4.追加機能④「モザイク処理」
5.追加機能⑤「白色化処理」
6.プログラムのダウンロード
7.まとめ
8.お願いとお断り

0.基本的な使い方と名称について

(1)起動方法

このアイコンをダブルクリックして起動します。

現在表示されているデスクトップ画面(の一部)をキャプチャするのが、このプログラムの主たる目的なので、メイン画面は起動時には表示されません。

起動時の画面
トースト通知(Toast Notification)の表示は Windows の設定により、出ない場合もあります。


元々、このプログラムを作ろうと思ったいちばんの理由は、『マウスカーソルの形状を含めて画面をキャプチャする必要が生じ、探した範囲では手軽に使えるアプリが見つからなかったので、それなら自分で書こうと思った』ことです。なので、この機能をいちばん最初に実装しました。

チェックボックスをチェックすればカーソルも含めて画面をキャプチャできます。

(2)キャプチャ方法

ショートカットキー「Shift+Ctrl+C」で現在表示されている画面全体をキャプチャできます(画面を指定してキャプチャすることはできません)。キャプチャした画像は「静かに」プログラムのメイン画面へと送られ(表示され)ます。その際、メッセージ等は何も表示されません。

キャプチャ後、タスクバーにあるオレンジ色のアイコンをクリックすると、メイン画面が表示されます。

もちろん、自分自身のキャプチャも可能です。
画面右側にキャプチャした画像のサムネイルが表示されます。


(3)操作パネルの位置の変更

上の図に示したように、操作パネルは「メイン画面の上部/下部」いずれかへの配置を選択できるようにしました。

画面上部に操作パネルを表示する場合です。
(設定は即適用&自動的に保存され、次回起動時に適用されます)


(4)ラバーバンド形状

ラバーバンドの形は、円形も選択できるようにしました。Shiftキーを押しながらドラッグすることで、矩形を選択している場合は「四角形 → 正方形」、円形を選択している場合は「楕円 → 正円」へとラバーバンドの形状が変化します。なお、いったん、四角形(長方形)や楕円のラバーバンドを描画し、その後、ラバーバンドのグラブハンドルをクリックしてリサイズする場合も、Shiftキーを押しながら操作すると、ラバーバンドの形状は「四角形 → 正方形」or 「楕円 → 正円」へ変化します。

ラバーバンドの形状は「矩形」or「円形」いずれかを選択できます。


ラバーバンドの線については、太さと色を指定できます。プログラムは、終了時の設定を自動的に記録し、次回起動時は前回終了時の設定を読み込んで(=復元して)起動します。

線の太さは10段階で指定可能です。


色は、TColorBox のデフォルトの設定色3種類から選べます。

上記3種類にチェックがある場合、
2つ上の図の TColorBox には184色が選択可能な Item として設定されました。


(5)処理一覧

あとは、「画像をそのまま保存」したり、「矩形/正方形/楕円/正円のいずれかのラバーバンドでさらにキャプチャしたい範囲を選択して、選択範囲内で右クリックすると表示されるメニューから選択できる処理を選んで実行する」ことが可能です。

このような解説画面を『とにかく簡単に』作りたくて作ったのが Capity です!


処理可能な画像数は、正直、自分でもよくわかりません。お使いの PC 環境(搭載しているメモリの大きさ等)により変化するものと思われます。保存するファイルの名称は、もちろん任意の名称を付けることも可能ですが、デフォルト設定では「 Screenshot_20251005_032342.png 」のように Screenshot_ に続けて西暦年月日時分秒が自動的に付くので、これまでファイルとして保存する際に面倒に感じていた「名前を付ける」作業から完全に解放されました。作った自分で言うのもナンですが、すごく便利です!!

・名称について

Capity という名称は、こちらも前回の記事で、『 AI に相談して決めた!』と書きましたが、その際 AI が示してくれたのが次の内容です。

・発音が柔らかく親しみやすい。技術系にも一般向けにも通用する響き。
・Capture + Simplicity / Utility / Clarity などの抽象的な価値を含められる造語。
・「City(都市)」や「Clarity(明快さ)」にも近い響きがあり、好ましい印象を与える。
・「キャプチャの能力(Capacity)」を連想させることもでき、機能性の高さを暗示。
・ロゴ・UI・ドメイン名・SNS ハンドルなどにも使いやすく、拡張性が高い。

それがほんとうか、どうかは使ってくださった方のお気持ち次第ではありますが・・・ 自分的には、この AI が示してくれた内容を具現化したプログラムになるよう、精一杯努力したつもり・・・です。

もちろん「特許情報プラットフォーム J-Plat Pat」で、特許・実用新案、意匠、商標の各権利について過去に、この名称での申請・登録のないことは確認済みです。(2025年10月5日現在)

1.追加機能①「開く」

最初は既存の画像を開く処理は不要と考え、実装していませんでしたが、簡単に実装できますし、「ない」よりは「ある」方がいいかと思い直して実装しました。ただ、あくまでもこのプログラムは、「現在表示されている画面を簡単にキャプチャする」ことが主な目的なので、ボタンの位置は深く考えずにほとんどおまけ程度に実装しましたので、ボタン自体の使い勝手はよくないと思います・・・。

ボタンクリックで TOpenDialog が表示されます。


ファイルを開く場合の Path の設定は、TOpenDialog の機能まかせ(=Windows まかせ)です。前回使用したフォルダが記憶されていれば、そのフォルダが自動的に選択されます。

表示したい画像を選択して、「開く」をクリックしてください。


表示された画像に対して、必要な処理を適用してください。

2.追加機能②「円形選択と保存・送信を可能に」

範囲を選択するのに使うラバーバンドは、矩形に加え、円形の形状をしたものも使えるようにしました。さらに Shift キーを押しながらドラッグすることにより、正方形や正円も描画できます。

目的に応じて使い分けてください。
(この画像も自分自身で作成しました)


(1)円形選択時の保存処理

画像の保存について解説します。ラバーバンドの形状が矩形・円形のいずれであっても、画像の保存形式は BMP ・ PNG ・ JPEG から選んで1種類を指定できます。

デフォルト設定は PNG 形式ですが、ここでは JPEG 形式が選ばれています。


キャプチャした画像の一部をラバーバンドで範囲選択し、選択した範囲内の任意の位置を右クリックすると次のようなサブメニューが表示されます。ここでは、まず、保存の処理から順に説明します。

表示されるメニューのコマンドは、すべてラバーバンド内のみに限って適用されます。


ラバーバンドが円形の場合、画像の保存時には注意が必要です。ラバーバンドの枠の内部の画像のみ保存対象とするのは、画像の形式によらず共通ですが、BMPとJPEG形式で保存する場合、枠外部分の透明化処理は行われず、枠外の部分は「白に塗りつぶされ」て保存されます。

「いいえ」をクリックした場合は、保存の処理自体がキャンセルされます。


保存された画像(例:BMP形式の場合)です。

青の部分がきれいに保存されています。


保存された画像(例:JPEG形式の場合)です。

圧縮処理が行われたため、青や緑が濃くなっています。


PNG 形式で保存する場合、次のメッセージが表示されます。用途に応じてラバーバンドの枠外の部分を「透明化する」もしくは「白く塗りつぶす」いずれかの処理を選択できます。

使用目的に合わせて処理を選択してください。


PNG 形式かつ「透明化あり」で保存した画像をフォトで見た場合です。

透明化した部分は黒くなっています。

同じ形式で「透明化なし・枠外を白く塗りつぶして保存」した場合の画像をフォトで見ると・・・

こちらは枠外の部分が黒くなっていません(当然ですが)


PNG 形式かつ「透明化あり」で保存した画像をパワーポイントに挿入してみました!

ラバーバンドの枠外が透明化されています。


同じ画像をWordに挿入してみました。

いったん保存してから挿入を行った結果です。


このように、PNG 形式かつ「透明化あり」で保存した画像は、「挿入」することで透明化処理が適用された状態で再利用できます。

(2)円形選択時のクリップボードへの送信

次に、クリップボードへの送信について説明します。

ラバーバンド内を右クリックして表示されるメニューから
「クリップボードへ送る」をクリックしてください。


ラバーバンドの枠が円形指定で、さらに範囲選択した部分を PNG 形式でクリップボードへ送信する場合、次のメッセージが表示されます。


「はい」を選んだ場合、例えば古いお絵描きソフトで背景色「黒」の画像を新規に作成しておいて、そこに円形(楕円)選択した範囲をクリップボードへ送信して(クリップボード経由で)貼り付けてみました。なお、このような場合には「背景色を透過色として貼り付ける(と同等の機能を利用して実行する)」必要があります。

思い出せないくらい、ながーい間愛用しているお絵描きソフトに
「背景色を透過色として」貼り付けてみました。


こちらが貼り付けた結果です。


背景が白の画像を円形で範囲選択して、背景が白の画像にクリップボード経由で貼り付けると困ったことになりますので、注意してください。

黒い字の部分が読めなくなってしまいます・・・


BMP や JPEG 形式を選択してクリップボードへ送信した場合は、次のメッセージが表示されます。


BMP 形式を選択し、表示されたメッセージの「はい」を選択して、クリップボードへ送信したデータを Word に貼り付けてみました。

ヒトの顔の切り抜きとか、そういう用途には使えるカモしれません。


この円形のラバーバンドに関する処理は、矩形時のそれにくらべると、要した時間は3倍以上かかっていると思います。とにかくない袖にタオルと雑巾を付け足して作った袖を振り回し、なんでもいいや、とにかくすーぱー頑張って作成しましたが、自分自身がこの円形のラバーバンドを使用する機会は今回限りであるような気が・・・。どこかで、どなたさまかのお役に立ってほしいと切に祈ります。

3.追加機能③「ぼかし処理」

ほんとうのことを言うと、円形のラバーバンドよりこちらを先に作成したのですが、出来たら実装したかった機能のひとつがこの「ぼかし処理」です。より低速になるのはわかりきっていましたが、搭載するならボックスブラーではなく、ガウシアンブラーと決めていました。

理由はただひとつ。少しくらい遅くても、「美しさ」を優先したかったのです。

ぼかす元画像です。


Box ぼかしを適用した画像です。

速いのですが、どうしてもジャギーな感じになります。

レベルは 10 まで指定できます。


ガウスぼかしを適用した画像です。

ごく自然な感じでぼかせます。
(レベルは5です)


文字にもガウスぼかしをかけてみました。レベルは5です。

ぼかす前の文字のある画像
ラバーバンドの内部をぼかした画像


ガウスぼかしとボックスぼかしのコードのセットです。ガウスぼかしのコードの↓に、ボックスぼかしのコードがあります。Boxぼかしに変更するときは、ガウスぼかしの変数はそのまま、var 宣言部の count 変数だけコメントアウトを解除してください。コード部分は、ガウスぼかしのコードをすべてコメント化して、Box ぼかしのコメントアウトを解除してください。

procedure TForm1.HandleGaussianBlur(Sender: TObject; const SelRectOnParent: TRect);
var
  //ガウスぼかし
  bmpSrc, bmpTemp: TBitmap;
  x, y, dx, dy, i, j: Integer;
  //固定小数点演算のため Int64 を使用 (合計値が非常に大きくなるため)
  r, g, b: Int64;
  radius: Integer;
  //カーネルを固定小数点値 (Int32) の配列として定義し直す
  kernel: array of Int32;
  pSrc, pTemp: PByteArray;
  blurLevel: Integer;
  selRectLocal: TRect;

  cx, cy, rx, ry: Double;
  IsEllipse: Boolean;

  //Box ぼかし
  //count: integer;  //Box ぼかしをかける場合はここのコメントアウトを解除する

  //ガウスカーネル生成関数(固定小数点対応版)
  function CreateGaussianKernel(radius: Integer; var kernel: array of Int32): Double;
  var
    k: array of Double; //一時的に浮動小数点カーネルを作成
    sigma, sum: Double;
    i: Integer;
  begin
      //浮動小数点カーネルの計算
      SetLength(k, radius * 2 + 1);
    sigma := radius / 2.0;
    sum := 0.0;
    for i := -radius to radius do
    begin
      k[i + radius] := Exp(-Sqr(i) / (2 * Sqr(sigma)));
      sum := sum + k[i + radius];
    end;

    //正規化と固定小数点へのスケーリング
    for i := 0 to High(k) do
      //正規化して SCALE_VALUE を乗算し、整数に丸める
      kernel[i] := Round((k[i] / sum) * SCALE_VALUE);
    Result := sigma;
  end;

  function IsInsideEllipse(x, y: Integer): Boolean;
  var
    dx, dy: Double;
  begin
    dx := (x - cx) / rx;
    dy := (y - cy) / ry;
    Result := (dx * dx + dy * dy) <= 1.0;
  end;

begin

  //ガウスぼかし
  if not Assigned(imgPreview.Picture.Graphic) then Exit;

  PushUndo;

  selRectLocal.TopLeft :=
    imgPreview.ScreenToClient(plImage1.Parent.ClientToScreen(SelRectOnParent.TopLeft));
  selRectLocal.BottomRight :=
    imgPreview.ScreenToClient(plImage1.Parent.ClientToScreen(SelRectOnParent.BottomRight));

  Screen.Cursor := crHourGlass;

  bmpSrc := TBitmap.Create;
  try
    bmpSrc.PixelFormat := pf24bit;
    bmpSrc.SetSize(imgPreview.Picture.Width, imgPreview.Picture.Height);
    bmpSrc.Canvas.Draw(0, 0, imgPreview.Picture.Graphic);

    bmpTemp := TBitmap.Create;
    try
      bmpTemp.PixelFormat := pf24bit;
      bmpTemp.SetSize(bmpSrc.Width, bmpSrc.Height);

      blurLevel := TrackBar1.Position;
      radius := EnsureRange(blurLevel, 1, 10);
      SetLength(kernel, radius * 2 + 1);
      CreateGaussianKernel(radius, kernel);

      IsEllipse := (RadioGroup1.ItemIndex = 1);
      if IsEllipse then
      begin
        cx := (selRectLocal.Left + selRectLocal.Right) / 2;
        cy := (selRectLocal.Top + selRectLocal.Bottom) / 2;
        rx := (selRectLocal.Right - selRectLocal.Left) / 2;
        ry := (selRectLocal.Bottom - selRectLocal.Top) / 2;
      end;

      // 横方向ブラー
      for y := selRectLocal.Top to selRectLocal.Bottom - 1 do
      begin
        pSrc := bmpSrc.ScanLine[y];
        pTemp := bmpTemp.ScanLine[y];
        for x := selRectLocal.Left to selRectLocal.Right - 1 do
        begin
          if IsEllipse and not IsInsideEllipse(x, y) then
          begin
            pTemp[x * 3 + 2] := pSrc[x * 3 + 2];
            pTemp[x * 3 + 1] := pSrc[x * 3 + 1];
            pTemp[x * 3 + 0] := pSrc[x * 3 + 0];
            Continue;
          end;

          r := 0; g := 0; b := 0;
          for dx := -radius to radius do
          begin
            i := EnsureRange(x + dx, 0, bmpSrc.Width - 1);
            r := r + Int64(pSrc[i * 3 + 2]) * kernel[dx + radius];
            g := g + Int64(pSrc[i * 3 + 1]) * kernel[dx + radius];
            b := b + Int64(pSrc[i * 3 + 0]) * kernel[dx + radius];
          end;
          pTemp[x * 3 + 2] := Byte(r shr SCALE_SHIFT);
          pTemp[x * 3 + 1] := Byte(g shr SCALE_SHIFT);
          pTemp[x * 3 + 0] := Byte(b shr SCALE_SHIFT);
        end;
      end;

      // 縦方向ブラー
      for x := selRectLocal.Left to selRectLocal.Right - 1 do
      begin
        for y := selRectLocal.Top to selRectLocal.Bottom - 1 do
        begin
          if IsEllipse and not IsInsideEllipse(x, y) then
            Continue;

          r := 0; g := 0; b := 0;
          for dy := -radius to radius do
          begin
            j := EnsureRange(y + dy, 0, bmpSrc.Height - 1);
            pTemp := bmpTemp.ScanLine[j];
            r := r + Int64(pTemp[x * 3 + 2]) * kernel[dy + radius];
            g := g + Int64(pTemp[x * 3 + 1]) * kernel[dy + radius];
            b := b + Int64(pTemp[x * 3 + 0]) * kernel[dy + radius];
          end;
          pSrc := bmpSrc.ScanLine[y];
          pSrc[x * 3 + 2] := Byte(r shr SCALE_SHIFT);
          pSrc[x * 3 + 1] := Byte(g shr SCALE_SHIFT);
          pSrc[x * 3 + 0] := Byte(b shr SCALE_SHIFT);
        end;
      end;

      imgPreview.Canvas.CopyRect(selRectLocal, bmpSrc.Canvas, selRectLocal);

    finally
      bmpTemp.Free;
    end;
  finally
    bmpSrc.Free;
    Screen.Cursor := crDefault;
  end;


  //BoxBlurを試す場合は、上のガウスぼかしのコードをすべてコメントアウトする
  //BoxBlur
  {
  if not Assigned(imgPreview.Picture.Graphic) then Exit;

  PushUndo;

  selRectLocal.TopLeft :=
    imgPreview.ScreenToClient(plImage1.Parent.ClientToScreen(SelRectOnParent.TopLeft));
  selRectLocal.BottomRight :=
    imgPreview.ScreenToClient(plImage1.Parent.ClientToScreen(SelRectOnParent.BottomRight));

  Screen.Cursor := crHourGlass;

  bmpSrc := TBitmap.Create;
  try
    bmpSrc.PixelFormat := pf24bit;
    bmpSrc.SetSize(imgPreview.Picture.Width, imgPreview.Picture.Height);
    bmpSrc.Canvas.Draw(0, 0, imgPreview.Picture.Graphic);

    bmpTemp := TBitmap.Create;
    try
      bmpTemp.PixelFormat := pf24bit;
      bmpTemp.SetSize(bmpSrc.Width, bmpSrc.Height);

      blurLevel := TrackBar1.Position;
      radius := EnsureRange(blurLevel, 1, 10);

      IsEllipse := (RadioGroup1.ItemIndex = 1);
      if IsEllipse then
      begin
        cx := (selRectLocal.Left + selRectLocal.Right) / 2;
        cy := (selRectLocal.Top + selRectLocal.Bottom) / 2;
        rx := (selRectLocal.Right - selRectLocal.Left) / 2;
        ry := (selRectLocal.Bottom - selRectLocal.Top) / 2;
      end;

      // 横方向ボックスぼかし
      for y := selRectLocal.Top to selRectLocal.Bottom - 1 do
      begin
        pSrc := bmpSrc.ScanLine[y];
        pTemp := bmpTemp.ScanLine[y];
        for x := selRectLocal.Left to selRectLocal.Right - 1 do
        begin
          if IsEllipse and not IsInsideEllipse(x, y) then
          begin
            pTemp[x * 3 + 2] := pSrc[x * 3 + 2];
            pTemp[x * 3 + 1] := pSrc[x * 3 + 1];
            pTemp[x * 3 + 0] := pSrc[x * 3 + 0];
            Continue;
          end;

          r := 0; g := 0; b := 0;
          count := 0;
          for dx := -radius to radius do
          begin
            i := EnsureRange(x + dx, 0, bmpSrc.Width - 1);
            r := r + pSrc[i * 3 + 2];
            g := g + pSrc[i * 3 + 1];
            b := b + pSrc[i * 3 + 0];
            Inc(count);
          end;
          pTemp[x * 3 + 2] := Byte(r div count);
          pTemp[x * 3 + 1] := Byte(g div count);
          pTemp[x * 3 + 0] := Byte(b div count);
        end;
      end;

      // 縦方向ボックスぼかし
      for x := selRectLocal.Left to selRectLocal.Right - 1 do
      begin
        for y := selRectLocal.Top to selRectLocal.Bottom - 1 do
        begin
          if IsEllipse and not IsInsideEllipse(x, y) then
            Continue;

          r := 0; g := 0; b := 0;
          count := 0;
          for dy := -radius to radius do
          begin
            j := EnsureRange(y + dy, 0, bmpSrc.Height - 1);
            pTemp := bmpTemp.ScanLine[j];
            r := r + pTemp[x * 3 + 2];
            g := g + pTemp[x * 3 + 1];
            b := b + pTemp[x * 3 + 0];
            Inc(count);
          end;
          pSrc := bmpSrc.ScanLine[y];
          pSrc[x * 3 + 2] := Byte(r div count);
          pSrc[x * 3 + 1] := Byte(g div count);
          pSrc[x * 3 + 0] := Byte(b div count);
        end;
      end;

      imgPreview.Canvas.CopyRect(selRectLocal, bmpSrc.Canvas, selRectLocal);

    finally
      bmpTemp.Free;
    end;
  finally
    bmpSrc.Free;
    Screen.Cursor := crDefault;
  end;
  }
end;

4.追加機能④「モザイク処理」

もうひとつ、出来たら実装したかったのが指定範囲に「モザイクをかける」処理です。文字情報を隠す用途であれば、強くぼかし処理する(or 重ね掛けする)だけで十分な気もしましたが、私には「ぼかす」+「モザイクをかける」の二手間を1セットにして文字情報を隠したい場合に画像を処理するクセがあり(このブログの過去記事を見ていただければ理解していただけると思います)、今回も2つで1セットのような気がして・・・。

モザイク処理する元画像です。


とりあえず、レベル5を設定して・・・

レベルは10まであります。


モザイク処理してみた結果です。ボックスぼかしみたいですね。なのでボックスぼかしは実装しませんでした。


文字をモザイク処理してみました。レベルは5です。

モザイクをかける前の画像
モザイク処理したラバーバンド内は、色の違いしか、わからなくなりました!


モザイクをかける処理のコードです。ご参考まで。

procedure TForm1.HandlePixelation(Sender: TObject; const SelRectOnParent: TRect);
var
  selRectLocal: TRect;
  bmpSrc: TBitmap;
  startX, startY: Integer;
  dx, dy: Integer;
  blockSize: Integer;
  r, g, b, count: Integer;
  pLineRead, pLineWrite: PByteArray;
  BlockWidth, BlockHeight: Integer;
  cx, cy, rx, ry: Double;
  IsEllipse: Boolean;

  function IsInsideEllipse(x, y: Integer): Boolean;
  var
    dx, dy: Double;
  begin
    dx := (x - cx) / rx;
    dy := (y - cy) / ry;
    Result := (dx * dx + dy * dy) <= 1.0;
  end;

begin

  if not Assigned(imgPreview.Picture.Graphic) then Exit;

  PushUndo;

  selRectLocal.TopLeft :=
    imgPreview.ScreenToClient(plImage1.Parent.ClientToScreen(SelRectOnParent.TopLeft));
  selRectLocal.BottomRight :=
    imgPreview.ScreenToClient(plImage1.Parent.ClientToScreen(SelRectOnParent.BottomRight));

  bmpSrc := TBitmap.Create;
  Screen.Cursor := crHourGlass;

  try
    bmpSrc.PixelFormat := pf24bit;
    bmpSrc.SetSize(imgPreview.Picture.Width, imgPreview.Picture.Height);
    bmpSrc.Canvas.Draw(0, 0, imgPreview.Picture.Graphic);

    blockSize := EnsureRange(TrackBar2.Position, 2, 50);

    IsEllipse := (RadioGroup1.ItemIndex = 1);
    if IsEllipse then
    begin
      cx := (selRectLocal.Left + selRectLocal.Right) / 2;
      cy := (selRectLocal.Top + selRectLocal.Bottom) / 2;
      rx := (selRectLocal.Right - selRectLocal.Left) / 2;
      ry := (selRectLocal.Bottom - selRectLocal.Top) / 2;
    end;

    startY := selRectLocal.Top;
    while startY < selRectLocal.Bottom do
    begin
      startX := selRectLocal.Left;
      while startX < selRectLocal.Right do
      begin
        r := 0; g := 0; b := 0; count := 0;

        BlockWidth := blockSize;
        if startX + BlockWidth > selRectLocal.Right then
          BlockWidth := selRectLocal.Right - startX;

        BlockHeight := blockSize;
        if startY + BlockHeight > selRectLocal.Bottom then
          BlockHeight := selRectLocal.Bottom - startY;

        //平均色の計算(楕円内のみ)
        for dy := 0 to BlockHeight - 1 do
        begin
          pLineRead := PByteArray(bmpSrc.ScanLine[startY + dy]);
          for dx := 0 to BlockWidth - 1 do
          begin
            if IsEllipse and not IsInsideEllipse(startX + dx, startY + dy) then
              Continue;

            r := r + pLineRead[(startX + dx) * 3 + 2];
            g := g + pLineRead[(startX + dx) * 3 + 1];
            b := b + pLineRead[(startX + dx) * 3 + 0];
            Inc(count);
          end;
        end;

        if count > 0 then
        begin
          r := r div count;
          g := g div count;
          b := b div count;
        end;

        //平均色の適用(楕円内のみ)
        for dy := 0 to BlockHeight - 1 do
        begin
          pLineWrite := PByteArray(bmpSrc.ScanLine[startY + dy]);
          for dx := 0 to BlockWidth - 1 do
          begin
            if IsEllipse and not IsInsideEllipse(startX + dx, startY + dy) then
              Continue;

            pLineWrite[(startX + dx) * 3 + 2] := r;
            pLineWrite[(startX + dx) * 3 + 1] := g;
            pLineWrite[(startX + dx) * 3 + 0] := b;
          end;
        end;

        Inc(startX, blockSize);
      end;
      Inc(startY, blockSize);
    end;

    imgPreview.Canvas.CopyRect(selRectLocal, bmpSrc.Canvas, selRectLocal);

  finally
    bmpSrc.Free;
    Screen.Cursor := crDefault;
  end;

end;

ガウスぼかし + モザイク処理の結果です。レベルはどちらも5です。

未処理の画像です。
ラバーバンド内をガウスぼかし + モザイク処理(ともにレベルは5)

5.追加機能⑤「白色化処理」

つい、(不要なのに)マウスの形状を含めてキャプチャしちゃった! みたいな場合、役に立つかも・・・と考え、実装しました。私の場合、背景色は「白」であることが多いので、単に指定範囲を「白で塗りつぶす」処理です。

不要なマウスカーソルまでキャプチャしちゃった!


マウスカーソル部分を範囲選択して右クリック、メニューの「白色化」をクリックします。


不要なカーソルは消えました☆

これだけです!!!

【追記_20251006】

ぼかし加工やモザイク処理を行った画像データが保存できない不具合を修正しました。この修正に合わせて、ぼかし加工やモザイク処理、及び白色化等、画像データを加工した場合は、任意の段階で「保存」ではなく、メモリ上の表示用データに「反映」する機能を追加しました。具体的には、次の通りです。

次の図のように画像の一部を加工します。例:白色化

画面右のサムネイルには変更が反映されていません。


この状態で、画面右のサムネイルをクリックすると、画像に設定した変更内容はすべて破棄され、加工前の画像が表示(復元)されます。加工状態がサムネイルに反映されていない状態でのサムネイル・クリックは、「一気に元に戻す処理になる」とお考えください。

メモリ上の画像データの更新は「反映(英語表記は Apply)」ボタンをクリックすることで実行できます。

ちいさなボタンですが・・・


このボタンをクリックすることで、メモリ上の画像データが、メイン画面に表示されている加工した状態の画像データに更新されます。

画面右のサムネイルにも変更が反映されます。


このようにメモリ上のデータの更新処理をユーザー側に委ねることで、Undo / Redo の履歴操作とサムネイル更新が完全に分離され、処理の整合性が保たれるようにしました。

初期バージョンで作者の保存機能に関する確認作業が至らなかったため、ご迷惑をおかけした皆さまに、こころからお詫び申し上げます。誠に申し訳ありませんでした。

現在、未発見の不具合が見つかりました場合は、こちらで報告し、速やかに修正版を掲載いたしますので、万一、お使いいただける場合は、修正版のアップロードの有無にご注意いただけましたら幸いです。

【追記_20251007】

自分で使っていて(そのために作ったプログラムですが)、画面のキャプチャだけでなく、クリップボードに画像データがある場合、それをショートカットキー( Ctrl + V )で貼り付けて、さらに加工等できたらいいなぁ・・・ と思いましたので、本日即、実装しました。

ショートカットキーを利用して、このプログラムのメイン画面に貼り付け可能な画像形式は、BMP、PNG、JPEG、GIF、TIFF に加え、画像の読み込みに必要な外部ライブラリが導入されていれば、HEIC や WebP にも対応可能と思われます。※ すべての画像形式について、その読み込みの可否に関する動作検証は行っておりません。もし、クリップボードにあるデータが、このプログラムで読み込めない画像データであった場合には、その旨を伝えるメッセージが表示されます。

また、乱暴な言い方で申し訳ないのですが、プログラムのバージョン管理は、まったく考えておりませんでしたので、この下のダウンロードリンクからダウンロードできるものが最新版です。

このプログラムは EXE ファイル1つで単体動作します(プログラム終了時の VCL コントロールの諸設定は C:\Users\ユーザー名\AppData\Roaming\Capity\settings.ini に保存されますが、この ini ファイルはなくてもプログラムは動作します)。また、レジストリは一切汚しておりませんので、 EXE ファイルを上書きすれば、プログラムの更新作業は完了します。

【追記_20251009】

自分で使っていて欲しいと思った機能をさらに追加しました。それは、矢印キーによるラバーバンドの移動と、形状の微調整です。以下、具体的な操作方法です。

移動方法:ラバーバンドが選択(Visible)されている状態で、Shiftキー + Ctrlキー + 各矢印キー押し下げで、現在の幅と高さを保ったまま、押し下げた矢印キーの方向に1ピクセルずつ移動できます。

形状の微調整:Shiftキー + 右向き矢印キーで幅を1ピクセルずつ増加、Shiftキー + 左向き矢印キーで幅を1ピクセルずつ減少、Shiftキー + 上向き矢印キーで高さを1ピクセルずつ減少、Shiftキー + 下向き矢印キーで高さを1ピクセルずつ増加させることができます。

【追記_2025_1012-1025】

さらに複数の機能を追加しました。追加した機能は、次の通りです。

(1)起動時に自動消音

操作時の Beep 音が気になるので、起動時に自動消音するようにしました。

起動直前の音量設定は保存されており、終了時に復元されます。


(2)グレイスケール / セピア 色の画像に変換

表示されている画像を、Grayscale もしくは Sepia いずれかの画像へ変換できるようにしました。

変換元の画像


・グレースケールに変換

グレースケールに変換


・セピアに変換

Sepia を指定した場合は、その強度を 0.1 ~ 1.0 の範囲で設定できます。

セピア色変換の強度を指定


強度「1.0」で変換した例です。

セピア色に変換


(3)背景色の切り替え

表示する画像に応じて、背景色を「白/黒」のいずれかに指定できるようにしました。背景が「白」の画像を表示する際は、背景色に「黒」を指定すると画像境界が明確になります。

背景色は「白」を指定した状態です。


背景色が「白」だと、画像の境界がわからない場合があります。


背景色を「黒」に切り替えました。画像の境界が明瞭になり、範囲選択しやすくなります。


なお、背景色の設定は、他の設定同様、終了時の設定が自動的に保存され、次回起動時は前回終了時の設定が復元された状態で起動します。

(4)回転

操作パネルの「回転」部分に任意の値を指定して「▶」ボタンをクリックしてください。正の値で時計回り(右回り)、負の値で反時計回り(左回り)に表示されている画像が回転します。

回転元画像です。

回転角度は、時計回りに3°を指定


「▶」ボタンクリックで回転が行われます。


メモリ上のデータに反映するか・どうかの確認が行われます。「はい」で反映され、「いいえ」で「取り消し処理(UnDo)」が実行されます。


(5)拡大と縮小

拡大と縮小処理を行います。100.00 %が等倍で、それより小さい値を指定すれば縮小、大きな値を指定すれば拡大されます。

縮小率 50 %を指定


うっすらと、図の周囲に灰色の線が描画されますが、ご容赦ください。


回転と同様に、メモリ上のデータに反映するか・どうかの確認が行われます。「はい」で反映され、「いいえ」で「取り消し処理(UnDo)」が実行されます。


(7)枠線

枠線部分はそのままですが、色は色名の表示をカットし、選択できる色数も減らしました。


(8)グラブハンドルの非表示

表示/非表示を切り替える CheckBox を追加

ラバーバンドのみ描画する状態も選択できるようにしました。工夫次第で次のような色枠で囲んだ画像を作成することもできます。


(9)表示している画像全体を選択可能にしました。クリアボタンクリックで選択を解除できます。


その他 1025 のアップデートでは、ラバーバンド内を右クリックすると表示されるサブメニューの項目の Enabled を設定可能とし、起動直後は「取り消し」処理が選べないようにしました。

6.プログラムのダウンロード

今回の記事で紹介した PC の画面キャプチャを実行するプログラム Capity Plus 一式を以下からダウンロードできます。なお、ダウンロードとご使用にあたっては、免責事項及び使用条件への同意が必要です。免責事項及び使用条件の詳細は付属の License.txt をご覧ください。

なお、プログラムの初回起動時には、Windows Defender SmartScreen による警告画面が表示されます。この警告画面に関する詳細は、当 Blog の次の過去記事をご参照ください。

7.まとめ

初期バージョンに追加した機能のまとめです。

(1)既存の画像も開けるようになりました。
(2)ラバーバンドの形状に円形( Drag : 楕円/Shft & Drag : 正円)を追加しました。
(3)操作パネルの位置を上 or 下に設定できるようにしました。
(4)クリップボードへの送信機能を円形対応にバージョンアップしました。
(5)指定範囲に「ガウスぼかし」をかけることができるようになりました。
(6)指定範囲を「モザイク処理」できるようになりました。
(7)指定範囲を「白色化」できるようになりました。
(8)終了時設定を C:\Users\ユーザー名\AppData\Roaming\Capity\settings.ini に自動保存。
(9)ショートカットキー( Ctrl + V )でクリップボードにある画像データを貼り付け。
(10)画像の加工内容をメモリ上の画像データに反映する機能を追加。
(11)起動時にボリュームが0より大きい場合は、自動消音します(終了時に元に戻る)。
(12)グレイスケール / セピア 色の画像に変換できます。
(13)背景色の切り替えが可能になりました(白と黒のいずれかを指定)。
(14)画像の回転(時計回り・反時計回り)
(15)画像の拡大と縮小

機能の追加(20251019)

(16)グラブハンドルの表示/非表示の切り替えが可能になりました。

機能の追加(20251025)

(17)表示している画像全体を選択・選択解除

全体として、「操作パネル」では「現在、表示されている画像全体の加工・設定」を行い、画像上をマウスでドラッグすることで描画される「ラバーバンドの内側」を右クリックすると表示されるサブメニューのコマンド群は、「ラバーバンドで指定した範囲内のみを加工・設定」するものとお考えいただけましたら幸いです。

【重要】
元に戻す( Ctrl + Z )際には、表示されている画像の状態をメモリ上のデータに「反映」させるか・どうかを問うメッセージは表示されません。これは「どこまで元に戻すのか?」の判定を自動で実行(判断)することが不可能なためです。ですので、どのタイミングで処理を「確定」させるかは、ユーザーサイドにお任せする仕様としてあります。もちろん、処理を「反映」させても元に戻す処理はある程度効きますが、画像への加工内容をメモリ上のデータに「反映」させるタイミングはあくまでもユーザーサイドでの判断に委ねる仕様ですので、この点につきましては十分ご留意ください。

また、画像を多量に扱うプログラムの場合は、メモリリークが心配ですので、プロジェクト・ソースの CapityPlus.dpr ファイルに以下のように” ReportMemoryLeaksOnShutdown := True ”を設定して、プログラムの終了後、もし、メモリリークがあればその状況を表示するようにして(あくまでも、私がテストした範囲内に限ってのことではありますが)プログラムが正常終了した際にメモリリークが発生しないことを確認済みです。

program CapityPlus;
uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  ReportMemoryLeaksOnShutdown := True;
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

8.お願いとお断り

このサイトの内容を利用される場合は、自己責任でお願いします。記載した内容(プログラムを含む)を利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。

作者が気がついた限りの範囲ではありますが、動作検証を行い、発生したエラー等の不具合は誠心誠意取り除いたつもりですが、まだまだ未発見のバグは必ずあると思います。もともと、このブログの記事を書くために開発したプログラムなので、今後も使用する中で発見できた不具合は、可能な限り速やかに修正して、こちらの記事で追加報告させていただきます。上記ダウンロードリンクからダウンロードできる版が最新版です。実行ファイル( exe )は単体で動作しますので、バージョンアップは旧版を削除して新版にするか、単に新版を旧版に上書きするだけで完了します。