だるろぐ

明日できることは、今日しない。

Shriken 1.0.0

f:id:daruyanagi:20200205180825j:plain

ブログ掲載のために画像をリサイズするだけのアプリ「Shriken」をリリースしました。「スマホ同期」で[共有]→ 画像をリサイズしてクリップボードへコピー → はてなブログへ貼り付ける というプロセスがちょっとだけ簡単になります*1

www.microsoft.com

とりあえずストアに出して、Surface Pro X で使いたいと思い(だから ARM64 ビルドもあるよ!)、不安定な機能は全部削除しているので、普通の人はあまりこれのお世話になることはないと思いますが、将来的には以下の機能が実装される予定です。

  • クロップ
  • 閲覧時のズーム
  • ペンによる注釈
  • 顔認識と笑い男化

ここまで完成すれば、まぁ、需要はなくもないんじゃないでしょうか。

ちなみに、名前が Shuriken ではなく Shriken なのは、他の人に名前がとられてたからです。でも、Shrink image からもじって付けようと思ってたので、あまり問題はない(キリッ

開発秘(?)話

久しぶりの UWP 開発だったので、どんな UI にしていいのかさっぱりわかりませんでした。

いろいろ試行錯誤した結果、標準アプリである「フォト」に似せればいいか、という考えに落ちつくまでに、View は3回ぐらい作り直しました。そのおかげで、最初はコードビハインドにべた書きしていた ViewModel、Model も分離されるようになり(だって、View 作り直すたびにコードビハインドをコピペするの大変じゃん?)、(あくまで個人的には)いい感じに設計できました。怪我の功名ってやつですね。機能追加してもそうそう破綻しなさそうです。

アプリを開発するうえでは、docs.microsoft.com のお世話になりました。最近は Web ページからサンプルアプリを起動して挙動を確認できるのね。すごくいいと思います。ドキュメントサイトはとかくディスられがちだけど、個人的には昔よりだいぶ良くなってると思います。チュートリアルというか、よくある処理の流れが一通り解説されたページや、似たような機能の違いを解説するページも増えてきて、「そう、それが知りたかったんだよ!」って思うことが増えました。かつては StackOverFlow : 公式ドキュメント:Kazuki さんのブログ = 6:1:3 ぐらいな参照比率でしたが、今回は 5:3:2 ぐらいだったかもしれない。

*1:たとえば「フォト」アプリだと、リサイズの幅・高さを微調整できないし、一度ファイルへ保存する必要があります

アマゾニストならダンボールストッカーは必須だと思った

前々から欲しかったんだけど、なんとなく買わずにいた段ボールストッカーを、先日とうとう買ってしまった。

f:id:daruyanagi:20200202173203j:plain

これまで、たまった段ボールはダイソンの掃除機立てで挟み、玄関に置いていたのだが、だんだん掃除機立ての方が耐えられなくなり、ネジが緩んでグラグラしてきたのだ。しかも、ネジひとつ、どこか行ってまうし……このまま放置するわけにもいかず、しぶしぶ購入と相成った。

f:id:daruyanagi:20200202173406j:plain

そのおかげで、こうじゃ! すごくスッキリして気持ちがいい。こんなことなら、もっと早くに買うべきだったぜ。

今回買った「山崎実業 そのまま結束できる ダンボール収納 ダンボールストッカー タワー ブラック 3304」にはキャスターもついているので、部屋から部屋への移動も楽だ。試しにリビングへ転がし、この前建築した食器棚の段ボールをまとめてみたが……スチールのフレームがしっかり段ボールを挟んでくれるので、とても結束しやすい。今までは段ボールを何枚も一生懸命太ももで挟んで……みたいに頑張ってたんだが、それは無駄な行為だった。

f:id:daruyanagi:20200202174401j:plain

ちなみに、この段ボールストッカーは下から紐を通してそのまま結束できるのが売りだが、この作業は割とダルかった。あらかじめ紐を這わしておいて、その上に段ボールを積んでいけばいいのだけど。その意味でも、なんかいい紐(+くるくる結束)のいい収め方はないものかと考えている。本体がスチール製だから、強力なマグネットフックか何かで引っ掛けられないだろうか。

ついでに言えば、このくるくる結束も、個人的にはかなりおすすめ。不器用で紐を結べない僕のようなクズでも、段ボールや雑誌がバラバラにならないようにできる。こういうインストゥルメントこそ文明の利器と呼ぶにふさわしい。

f:id:daruyanagi:20200203164217j:plain

今回買った段ボールストッカーは結局、トイレの前、リビングの入り口に置いておくことにした。幅、奥行きともにジャストフィットだ。一見ドアを開く邪魔になるように見えるが、何回か試したところ、支障はなさそうだ。段ボールがないときは、廊下の収納にそのままゴロゴロッと IN してしまえる。まさしくピッタリで、我が家に迎えるべくして迎えたアイテムと言えよう。

Surface Pro X が文鎮になりかけたけど、事なきを得た話

ARM64 の検証機として Surface Pro X を購入。さっそく、Windows Insider Program の Fast リングに加えた*1

というのも、Windows 10 の最新プレビュー版では「タスク マネージャー」がいい感じにアップデートされていて、プロセスのアーキテクチャーを簡単に確認できるのだ。

forest.watch.impress.co.jp

Google Chrome はともかく、DAX3API *2なんかも x86 で動いてるんだな。こういうのが ARM64 ネイティブになれば、バッテリーライフはもっと伸びると思う。

――それはさておき。

Build 19546 は無事に適用されたのだが、そこから Build 19551 へアップグレードするとき、それは起こった。

なぜか更新画面で文字化けが発生する。それだけならまだいいのだけど、アップグレードの完了後、PC を起動しても Windows ロゴから先に進めず、フリーズしてしまうようになった。

まぁ、Windows Insider Program は不具合上等のプレビュービルド。こういうこともあるよね、と思い、リカバリーを始めた。起動ディスクはまだ作ってなかったので、Microsoft のサポートページにアクセスして、Surface Pro X のイメージをもらわなければならない。しかし――

f:id:daruyanagi:20200202193248j:plain

おーまいがー、ふぁっきんしっと! もう一度再起動を試みるが、やはり起動しない。「まさかの文鎮というやつでは?」と一瞬焦ったが、ハードリセットを何回か繰り返すうちに、ロールバック処理が始まった。そう、最近の Windows 10 は Windows Update が原因で起動しなくなったことを検知すると、それをアンインストールして、元の環境を(できるだけ)復旧してくれるのだ。賢くなったよね、Windows 7 から乗り換える気になったよね!

この問題を「フィードバック Hub」に投げて、Twitter でも軽く言及すると、米国の Windows 10 チームのなかの人と思しき人からコンタクトがあり、「見たことないエラーだから詳細を教えてくれ」という。すでに「フィードバック Hub」へ投稿済みのリンクを教えてあげると、次の Build 19555 ではしっかり対処された。

教訓、教訓。

フィードバックはちゃんとしよう。結構直してくれるぞ! 自分の場合、「Bluetooth 機器のバッテリー残量を見れるようにしてほしい」とフィードバックしたところ、ちゃんとなかの人から「いいアイデアだな、そのうち付けるぜ!」と返事があって、実際に実装された。日本語 IME などのトラブルはとくに、日本人ユーザーが言わなければ改善されることはないので、積極的に文句を付けに行きたいところだ。

f:id:daruyanagi:20200202193942p:plain

*1:最初はなかなか新しいビルドが降ってこなくて、ARM64 端末は Windows Insider Preview に参加できないのかと思ったけど、そんなことはなかった

*2:Dolby Atmos 関連のプロセスらしい

食器棚を建設した

土曜日は Ameba で棋王戦第一局を観戦しながら、のんびりと食器棚を作った。今までは親父が旧居からもってきたキャビネットを代用していたのだけど、どうにもこうにも使いにくいし、デカいわりに収納力がない。親父もいなくなったことだし(アフリカに長期出張)、そのキャビネットはリビングに移動させて、キッチンを自分の使いやすいように大改造する決意なのだ。

うちのキッチンはちょうど 120cm の戸棚が入る。幅 90cm 程度のモノを買って、ごみ箱を置くスペースを作るか、幅めいいっぱいのものを買って収納を重視するかを少し悩んだけれど、結局は収納を重視することにした。収納があれば、その余裕でごみ箱を置くスペースは作れるけれど、その逆は無理そうなので。

箱は合計5つ。佐川急便のお兄さんが、一人で頑張って14回まで持ってきてくれた。どれから開ければいいのかわからんかったが、とりあえず開いたのがたまたまビンゴ。1つ目だったようで、組立説明書がでてきた。

そこで気が付いたんだけど、ちゃんと箱には「2/5」「5/5」といった感じで番号が振ってあった。何も運を試さずとも、「1/5」の箱を開ければよい。

まずは欠品がないか確認しながら開封してい……こうと思ったんだが、部品点数が多すぎてやる気をなくした。とりあえずリビングと和室にパーツを広げ、番号が近いものをまとめていく。梱包材と段ボールが山のように出てきて、捨てに行くことを考えると頭が痛い。

お昼過ぎから、組立説明書にしたがって棚を作っていく。

不思議なもので、最初は作るのが億劫だったのに、棚が一つ、二つできていくと、ちょっと楽しくなって、ペースが速まっていく。本当は二人で作れと書いてあったのだけど、あいにく同居人はこんな感じなので役に立たない。

f:id:daruyanagi:20200129093809j:plain

ただ、マキタの充電式ドライバドリルは大変役に立ってくれた。説明書には「ドライバーが必要」と書いていたけど、正直、ドライバー一本だったら半日では終わらなかったと思う。

少し進めてはお酒飲んで休憩し、休憩しては少し進めと、ゆっくり組み立てていく。

この説明書は上の段から組んでいくように指示しているのだけど、たぶん下の段から作った方がわかりやすいと思う。下から順にくみ上げてさえいれば、上の段のスチール部分を逆にくっつけてしまい、外して付け直す羽目にはならなかっただろう。

f:id:daruyanagi:20200201231620p:plain
約2名を暗殺リストに追加

8時前になり、ようやく大まかな部分が完成した。

実働で3時間ぐらいはかかっただろうか。2人だったら2時間かからずにできたと思う。

棚と扉を付けて、ちゃんと完成したのは午後11時。最後はちょっと疲れちゃって、作業が雑になったせいか、扉がちょっとずれてるような気はするけど、まぁまぁ、うまくいった。

この製品は組立説明書も丁寧で(ちゃんとパーツ名をいちいち書いていてくれる)、とても分かりやすい。さっき言ったように、組立順序には個人的に疑問を持っているけれど、まぁ、たいした問題ではないと思う。いくつか注文を付けるなら、コンセントは首折れタイプにしてほしいかな。

f:id:daruyanagi:20200201194441j:plain

食器棚を壁にぴったりつけようと思うと、通常のタイプのコンセントではつっかえちゃうんだよね。これは L 字に曲がるタップをかまして解決した。あと、扉の蝶番は説明書のように、先に扉に組み付けるのではなく、食器棚側に軽く組み付ける方がよいと思う。そのあと扉の丸い穴に蝶番のもう一方を挟み、ネジを扉・棚を対角に締めていく方がやりやすいと思った。

まだ食器は収めていないのだけど、キッチンに鎮座していた電子レンジとオーブンが食器棚のオープンスペースに収まり、キッチンが広々として満足。炊飯器もスライドの上に置いた。水場に面したスチール部分には S 字フックを引っ掻ければ、ごみ袋なんかもつるせそうだ。

鈍川温泉で来島水軍の料理を堪能する

f:id:daruyanagi:20200126091956p:plain
鈍川温泉のキャラクター・鈍川まなみちゃん

確定申告の入力が済んだご褒美に、@ramusara を誘って週末は鈍川温泉に出かけた。松山市内からだるカーで北へ40分ほど、今治の手前の山中にあるひっそりとした温泉だ。

旅館に着くと、ベッドが二つ置かれたいい感じの和室に通された。ダブルじゃなくてよかったか、少し心配されたけど、そういう趣味はない。年季が入っていてちょっと軋むけれど、ぐっすり眠れた。

ノートパソコンは Surface Pro X に SIM を刺してもってきたが、どうも電波の入りがよくない。室内ではアンテナ1本、窓際でようやく3本といった具合だ。@ramusara の WiMax も当然入らないので、Pixel 3 のテザリングでしのいだ。こちらの感度は十分で、問題なく使える。まぁ、深い谷のなか、デジタルデトックスには最適な環境といえる。

夕食前にさっそく温泉につかったが、すべすべしていいお湯だと思う。すべすべし過ぎて、夕飯のときに箸を取り落としてしまったぐらいだ。色白の肌は陶磁器のようにツルツルとなり、春を一足先撮りにした桜色に染まった。

宿は15,000円のプランにしたが、なかなかに豪華だった。

なかでも目玉は法楽焼という郷土料理。

今治の郷土料理。来島水軍が戦勝の際に食べたと言われ、来島水軍料理として親しまれている。市内の店のいくつかは年間を通して提供しており、季節ごとに旬の海の幸・山の幸を味わうことができる。

法楽焼の材料は、来島海峡で獲れた鯛と今治市桜井産の車海老が基本。鯛を中心とした盛りつけは料理人の腕の見せどころ。下に敷いた松葉から、さわやかな香りが漂う。味付けは塩のみ、絶妙な塩加減は長年の経験が成せる業だ。

法楽焼 - 【郷土料理ものがたり】

焼いた石を平たい鍋に敷き、その上に焼き上げたタイ、エビ、ホタテをのせ、豪快に日本酒を注ぎ込んでしばらく蓋をする。蓋を開けたときの磯と酒の香りを想像せよ。タイの頭は頬はぷりぷり、目の周りはでろっとしていて、醤油などつけずとも絶妙な塩加減が実の甘さを引き立ててくれる。

朝ごはんもなかなかで、ご飯3杯おかわりした。居心地がよいのであやうく連泊しそうになったが、そろそろ荷物をまとめて宿を出ることにしよう。

耐猫最強防具

f:id:daruyanagi:20200122180234p:plain

11月に8カ月の♂ネコをお迎えしたのだが、なかなか慣れてくれない。小さい頃に人と接することが少なかったようで、近づくと極度におびえる。まぁ、それだけなら別にいいのだけど、モノを片付けようと近寄ろうものなら、シャーっと威嚇して、噛んだり引っ掻かれたりするのは少し困る。どうしても手で触れなければならないときは、バイク用の冬グローブをはめて自衛に努めていたが、ネコの爪や牙はそれすら貫通するのだ。

というわけで、防具を買った。

ドカタ時代によく使っていた革手が、肘まで伸びた感じ。少しサイズが大きな気もするが、革手というのは手にぴったりフィットしていなければならないものでもないし、あまり気にはならない*1

試しにこれを付けてネコにちょっかいをかけてみたが、ネコパンチごときでは傷一つ……ついたけど、なかまでは貫通しない。牙をたてられても、痛痒を感じない。これはかなりの防御力だ。今期のアニメに『痛いのは嫌なので防御力に極振りしたいと思います。』というのがあるが、その気持ちがよく分かった。ネコ氏のほうも、2、3回攻撃してまったく通用しないと悟ると、小さく唸ってプリンターの裏に引っ込んでしまった。見たか、これが文明の力だ!

f:id:daruyanagi:20200122181304p:plain

ネコには早く慣れてもらって、まず病院で異常がないかなどを確認したり、予防接種があれば受けさせたいのだけど、かなり時間がかかりそう。ストレスも感じてるみたいだし、なるべく無視して、無害な存在であることをアピールせねばなるまい。とはいえ、夜になると活動的になり、飼い主の上で踏んだり蹴ったりと元気なので、そんなに心配しないでもいいかなぁって思ってる。

*1:ドカタ時代は軍手の上に革手をしていたが、一度、クレーンのフックに指を持っていかれたとき、革手だけで済んで助かった

マモリ タイカレー&ガパオごはん 全10品セット ガパオ(鶏肉のバジル炒め)編

f:id:daruyanagi:20200121120715p:plain

Amazon で ヤマモリ タイカレー&ガパオごはん 全10品セット を購入してみたので、作ってみた。

今回は ガパオ(鶏肉のバジル炒め)に挑戦。ちなみに、「ガパオ」っていうのはカミメボウキと呼ばれるシソ科の植物、いわゆる「ホーリーバジル」と呼ばれる香草のことだとか。いままで「なんかタイあたりで作られてる挽肉+ごはん料理」のことを「ガパオ」と呼ぶのかと思ってたけど、思いっきり勘違いしていた。

f:id:daruyanagi:20200121120940p:plain

このレトルトにはガパオにブリッキーヌという赤唐辛子が含まれているとの由。パッケージの裏には辛さが5段階中上から4番目(4辛)と書かれている。もしかしたらちょっと辛いのかもしれない。

f:id:daruyanagi:20200121121526p:plain

パッケージに「※目玉焼きは含まれていません」とあったので、仕方なく(?)こちらで用意。ちょっと草を食べたかったので、ついでにレタスもみじん切りにして添えてみた。このレトルトは1個357円もするだけあって、ちゃんと鶏ひき肉がギッシリ詰まっている。魚醤だろうか、ちょっと変わったにおいがツンとただよってきて、食欲をそそられる。

味もなかなかよい。甘味よりは、ほんのちょっとだけ醤油辛さが勝っているか。ちょっと気になっていた辛さは、正直たいしたことがない。もう少し辛みを加えてもよいぐらいだが、このままでも十分おいしい。手を加える必要がない。量も申し分なく、これはリピートしてもいいかなって思った。

1月11日:バイクで大三島を一周してきた

※本当は Surface Pro X の開封記事を書く予定でしたが、ちょっとしたミスで発売日の受け取りに失敗したので、違うネタをお届けします(↓ こいつ、ウッキウキで Togetter にまとめてるんだろうなぁって思うと怒髪冠を衝く思いですが、わざわざ自分で事情を解説するのはもっと馬鹿らしいので、興味のある人は Togetter でも見てください。)。

三連休の初日。天気予報によると晴れるのはこの日だけのようなので、確定申告の準備はいったん棚上げし、バイクに乗る。行先は決めてなかったが、正月に S660 で大三島を半周したとき「バイクのほうが楽しそうだなぁ」と思ったのをふと思い出し、早速やってみることにした。

f:id:daruyanagi:20200114160009p:plain
今回のルート

大三島は、つま先を西に向けて短いブーツのような恰好をしており、その外周には県道51号線という環状線が敷かれている。しまなみ海道のインターから大三島に降りると51号線の東側に出るが、それを少し北にたどり、ちょうど足首部分を貫く県道21号線に折れて西進すると、山を抜けて島の反対方向にある大山祇神社へ素早く抜けられる。そのため、この51号線をわざわざぐるっと回る人はあまりいないが、一部を除き2車線が整備されているので割と走りやすい。海に向けて下る坂道、ちょっとエキサイティングだけどけっして難しくはないワインディング、鄙びた港……外周40kmほどだが、なかなかにバラエティに富んだ風景を楽しめる。波をかぶることがあるのか、道の上にたまに砂が浮いていること、落ち葉が広がる季節のあること、ときどき地元の人や自転車と出会うこと(学校もあるので子どもたちには注意)などに注意する必要はあるが、誰もいないところは誰もいないので、ちょっとハメを外すことだってできる。

f:id:daruyanagi:20200114163004p:plain

島は南回りで巡るのがよいだろう。左手に海を近くに感じることができる。ところどころに朽ちかけたモノレールがあるが、たぶんミカンを運ぶためのものだろう。ときどきバイクを止めて、それがどこまで続いているのか眺めてみても楽しい。

f:id:daruyanagi:20200114162916p:plain

島でごはんを食べるところはいくつかあるが、今回は道の駅で「マハタ」という魚の定食を食べた。「高級魚でしられるクエと同じハタ科の魚、プリプリとした触感と今注目されるコラーゲン」が売りだそうだが、値段はともかく、なかなかおいしかった。

f:id:daruyanagi:20200114164110p:plain

f:id:daruyanagi:20200114164320p:plain

寒風のなかバイクを駆ると、温泉に入ってあったまりたくなる。少し前まで、この島には「多々羅温泉しまなみの湯」という温泉施設があったが、残念ながら西日本豪雨で被災してしまった。

www.asahi.com

代わりに「しまなみドーム」というところにある温泉施設が使えるが、個人的には今治まで戻り、新しくできた喜助の湯に入るのがおすすめ。ラウンジはちょっと高いけど、岩盤浴、鳥かごチェア、ハンモック、地酒バー、マンガ、ファミコン・スーファミミニ、各種ボードゲームまでそろっている。追加料金さえ払えば、夜の11時以降も滞在可能。朝までゴロゴロできるので、カプセルホテルっぽく使うこともできるみたい。お風呂は何回でもはいれるし、お腹がすいたらご飯も食べられるので、飽きるまでゆっくりするといいだろう。

f:id:daruyanagi:20200114165217p:plainf:id:daruyanagi:20200114165333p:plainf:id:daruyanagi:20200114165310p:plainf:id:daruyanagi:20200114165241p:plain

「温泉は湯冷めするからちょっと……」という人は、来島海峡 SA の2階にあるマッサージチェアはどうだろう。来島海峡大橋の景色を眺めながら、タダで全身をモミモミしてくれる。15分ぐらいで次の人に譲るのがマナーだが、存在をあまり知られていないせいか、並んだり急かされることはいまだない。

f:id:daruyanagi:20200114165624p:plain

まだまだ書き足りないことがある気がするが、今日はここまで。Surface Pro X の発売日受け取りに失敗したショックから立ち直るためにも、早く寝る。

f:id:daruyanagi:20200114170333p:plain

UWP:SoftwareBitmap を縮小する

はてなブログにデカい写真を貼るときのフローがめんどくさい。どれぐらいめんどくさいかというと、ブログを書くペースが月1回に落ちるぐらいめんどくさい。

blog.daruyanagi.jp

――というわけで、年始は画像を縮小できるアプリを開発していた。要件は以下のとおり。

  • [共有]コマンドに対応(必須)
  • シンプル。ブログへのアップロードに使いそうな機能しか追加しない
    • 画像の縮小(できた)
    • 画像の回転(すぐできそうだけどやってない)
    • 顔認識して隠す(進捗半分)
    • 画像のクロップ(優先度低)

UWP アプリの開発は1年以上ぶりで、右も左もわからぬ。Microsoft Docs をさまよった結果、内部での画像データは SoftwareBitmap あたりで持つのがよさげだったが、当初は縮小の方法もいまいちわからかった。

Win2D を使う

そういうときは、やっぱり StackOverFlow だよね。親切にも SoftwareBitmap の拡張メソッドにしてくれていたので、そのまま使うことにした。ちなみに、これを利用するには NuGet で Win2D パッケージを別途インストールする必要がある。

// https://stackoverflow.com/questions/41251716/how-to-resize-a-softwarebitmap

public static SoftwareBitmap Resize(this SoftwareBitmap softwareBitmap, float newWidth, float newHeight)
{
    using (var resourceCreator = CanvasDevice.GetSharedDevice())
    using (var canvasBitmap = CanvasBitmap.CreateFromSoftwareBitmap(resourceCreator, softwareBitmap))
    using (var canvasRenderTarget = new CanvasRenderTarget(resourceCreator, newWidth, newHeight, canvasBitmap.Dpi))
    using (var drawingSession = canvasRenderTarget.CreateDrawingSession())
    using (var scaleEffect = new ScaleEffect())
    {
        scaleEffect.Source = canvasBitmap;
        scaleEffect.Scale = new System.Numerics.Vector2(newWidth / softwareBitmap.PixelWidth, newHeight / softwareBitmap.PixelHeight);
        drawingSession.DrawImage(scaleEffect);
        drawingSession.Flush();
        return SoftwareBitmap.CreateCopyFromBuffer(canvasRenderTarget.GetPixelBytes().AsBuffer(), BitmapPixelFormat.Bgra8, (int)newWidth, (int)newHeight, BitmapAlphaMode.Premultiplied);
    }
}

おおむね快適に動作するが、特定のサイズ(縦×横)の組み合わせで画像が乱れる問題が見つかったのが問題(割ったり、int でキャストしているところでなんかおかしいのかなぁ)。頑張って直してみようとしたが、自分には無理だった。

BitmapEncoder を用いる(WrietableBitmap 経由)

というわけで、基本に戻ることにした。BitmapEncoder を生成し、SoftwareBitmap を割り当てて、Transform してもらう。http://c5d5e5.asablo.jp/blog/2017/08/08/8642588 で提示されていたサンプルコードをベースに、SoftwareBitmap の拡張メソッドにしてみた。

// http://c5d5e5.asablo.jp/blog/2017/08/08/8642588

public static async Task<SoftwareBitmap> ResizeAsync(this SoftwareBitmap source, float newWidth, float newHeight)
{
    if (source == null) return null;

    using (var memory = new InMemoryRandomAccessStream())
    {
        // BitmapEncoder を用いメモリ上で source をリサイズ
        var id = BitmapEncoder.PngEncoderId;
        BitmapEncoder encoder = await BitmapEncoder.CreateAsync(id, memory);
        encoder.BitmapTransform.ScaledHeight = (uint)newHeight;
        encoder.BitmapTransform.ScaledWidth = (uint)newWidth;
        encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
        encoder.SetSoftwareBitmap(source);
        await encoder.FlushAsync();

        // リサイズしたメモリを WriteableBitmap に複写
        var writeableBitmap = new WriteableBitmap((int)newWidth, (int)newHeight);
        await writeableBitmap.SetSourceAsync(memory);

        // dest(XAML の Image コントロール互換)を作成し、WriteableBitmap から複写
        var dest = new SoftwareBitmap(BitmapPixelFormat.Bgra8, (int)newWidth, (int)newHeight, BitmapAlphaMode.Premultiplied);
        dest.CopyFromBuffer(writeableBitmap.PixelBuffer);

        return dest;
    }
}

Encoder から SoftwareBitmap を得るのに WrietableBitmap を経由しているのがあまりしっくりこないけど、こっちは問題なく動作した。

BitmapEncoder + BitmapDecorder

他人の力ばかり借りるのも何なので、自分でも考えてみたのはこちら。基本的にはさっきのやり方と変わらないけれど、WrietableBitmap ではなく、BitmapDecorder を利用している。

public static async Task<SoftwareBitmap> ResizeAsync2(this SoftwareBitmap source, float newWidth, float newHeight)
{
    if (source == null) return null;

    using (var memory = new InMemoryRandomAccessStream())
    {
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, memory);
        encoder.SetSoftwareBitmap(source);
        await encoder.FlushAsync();

        var decoder = await BitmapDecoder.CreateAsync(memory);

        var transform = new BitmapTransform()
        {
            ScaledHeight = (uint)newHeight,
            ScaledWidth = (uint)newWidth,
            InterpolationMode = BitmapInterpolationMode.Fant,
        };

        var dest = await decoder.GetSoftwareBitmapAsync(
            BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, 
            transform, 
            ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage
        );

        return dest;
    }
}

これも問題なく動いたが、どうも WrietableBitmap バージョンと比べると動作が遅い。Encoder/Decorder の生成にかなりコストがかかるようだ。となると、そもそも Encoder/Decorder は毎回生成せず、使いまわしたほうが良いのかもしれない(拡張メソッドにするのもあまりよくない、もしくは拡張メソッドに Encoder を渡すようにする)。

とりあえず、これで基本的な使い方はわかったような気がするので、画像の回転などは簡単に作れそう(Transform するだけ)。作るうちにペン対応なんかもやりだして、なかなか完成しないけれど、開発中のアプリはなかなかよく動いており、「ブログ、また書こうかな」っていう気がわいてきた。

スマホで写真を撮る → 「スマホ同期」アプリでコピー → はてなブログに張り付け

Window 10 の「スマホ同期」アプリのおかげで、スマホの写真を用いてブログを書くのがとても簡単に……ならない話。

f:id:daruyanagi:20200102045526p:plain

「スマホ同期」アプリというのは、PC とスマホの間でデータを同期するアプリ……ではなく、どっちかっていうと、PC からスマホを「のぞき込める(リモートアクセスできる)」アプリだと思う。スマホをポケットやカバンのなかにいれたまま、そのデータ(写真)にアクセスしたり、SNS/MMS のやり取りや通話が行える。

最近、この「スマホ同期」アプリのフォト機能が強化されて、リモートアクセスできる写真の数が 25 → 2,000 に拡充された。

forest.watch.impress.co.jp

25 枚しか同期できないときはたいして魅力に感じなかったが、2,000 ともなるとなかなか便利だ。たとえば――

f:id:daruyanagi:20200102045534p:plain

「スマホ同期」アプリでスマホの写真をコピーし、はてなブログに張り付ければ、そのまま写真がアップロードされる。[共有]コマンドで「切り取り&スケッチ」アプリをはさみ、ペンで書き込みを入れて貼り付けるというのも簡単だ。

f:id:daruyanagi:20200102045541p:plain

でも、ここで問題となるのが、はてなブログ側。アップロードできる画像のファイルサイズに制限があるので、単にコピーするだけではときどきアップロードに失敗してしまう。[共有]機能で他のアプリに送るにしても、「切り取り&スケッチ」アプリにはリサイズ機能がない。「フォト」アプリに送れば(なんで「スマホ同期」アプリから直接共有できないんだ?)リサイズ機能があるが、こいつはファイルを保存する。まぁ、保存したファイルを Web ブラウザーにドラッグ&ドロップすればいいんだけど、クリップボードで操作が完結しない(余計なマウス操作が必要になる)のは面倒だなー。

ってわけで、画像をリサイズするだけのプチアプリでも作るか、という気になっている。