アプリ置き場

アプリ置き場

http://www.moreread.net/

MaDotPaint V1.0.4

勢いでレイヤー機能も追加したった。

レイヤー構造っても透過画像重ねるだけなんでどうってことないのだけど、ファイルの保存で困った。レイヤーを扱うための一般的な画像形式ってないのだろうか?案外汎用的なフォーマットが見つからない。謎。
よくわかんないから、PNGに連番の名前つけてZIPで固めて保存した。独自の拡張子つけて。もう少し丁寧にやるならレイヤー名やらパレットとの紐付とか管理情報ファイルは別に入れたほうが良いきがするけど、とりあえずこれで足りてるかなー。
 
 

PixelFormat.Format8bppIndexedとGIFアニメ出力

これだとキャッチ―さが足りないのではないか。

 
せっかくペイントソフトも作った(http://www.moreread.net/)のでキャッチ―なドット絵を描きたい。描いてみよう。16x16サイズてきついな……。

描いたところでアニメーションさせてみたくなる。ということで簡易アニメーションビューワも作った。左上からZ字で指定の大きさでスキャンしてくだけのものだけど。

さらについでに画像の分割保存機能もつけた。よし、ついでにアニメーションGIFにしてまえ。DOBONさんのところにアニメーションGIFを吐き出すコードがあった。
 

!?
Bitmapクラス(32bpp)をそのままGIF指定で保存すると、デフォルトのパレットで誤差拡散されて無残な結果になってしまった。
どうも先に8bppIndexedカラー化しておかねばならないようだ。
ググっても見つからなかったのでとりあえずてきとうに書いた。
public static Bitmap GetIndexedBitmap(Bitmap orgBmp)
{
    if (orgBmp == null) return null;
 
    //処理時間計測
    Stopwatch sw = new Stopwatch();
    sw.Start();
 
    //元画像(32bpp)をバッファに読み出す
    BitmapData orgData = orgBmp.LockBits(new Rectangle(0, 0, orgBmp.Width, orgBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
    byte orgBuf = new byte[orgBmp.Width * orgBmp.Height * 4];
    Marshal.Copy(orgData.Scan0, orgBuf, 0, orgBuf.Length);
    orgBmp.UnlockBits(orgData);
 
    //出力先画像(8bppIndexed)の生成とバッファの取出し
    Bitmap indexedBmp = new Bitmap(orgBmp.Width, orgBmp.Height, PixelFormat.Format8bppIndexed);
    ColorPalette palette = indexedBmp.Palette;
    int boundaryWidth = ((indexedBmp.Width + 3) / 4) * 4;// 4Byte境界込みの幅
    BitmapData indexedData = indexedBmp.LockBits(new Rectangle(0, 0, indexedBmp.Width, indexedBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
    byte indexedBuf = new byte[boundaryWidth * indexedBmp.Height];
    Marshal.Copy(indexedData.Scan0, indexedBuf, 0, indexedBuf.Length);
 
    //元画像から色を抽出しつつパレットと画像の生成
    Dictionary<Color, int> dicPalette = new Dictionary<Color, int>();
    int count = 1;
    palette.Entries[0] = Color.FromArgb(1, 0, 0); //index 0 は透明色とする
    for (int i = 0; i < indexedBmp.Height; i++)
    {
        for (int j = 0; j < indexedBmp.Width; j++)
        {
            int pos_org = (i * indexedBmp.Width + j) * 4;
            int pos_indexed = i * boundaryWidth + j;
            Color c = Color.FromArgb(BitConverter.ToInt32(orgBuf, pos_org));
            if (c.A < 255)
            {
                indexedBuf[pos_indexed] = 0;
                continue;
            }
            if (!dicPalette.ContainsKey(c))
            {
                dicPalette.Add(c, count);
                palette.Entries[count] = c;
                count++;
                if (count > 255) count = 255;// 256色以上は非対応
            }
            int index = dicPalette[c];
            indexedBuf[pos_indexed] = (byte)index;
        }
    }
 
    //出力先画像(8bppIndexed)の後処理
    indexedBmp.Palette = palette;
    Marshal.Copy(indexedBuf, 0, indexedData.Scan0, indexedBuf.Length);
    indexedBmp.UnlockBits(indexedData);
 
    //計測結果出力
    sw.Stop();
    Console.WriteLine("[GetIndexedBitmap] time = " + sw.ElapsedMilliseconds + "ms");
 
    return indexedBmp;
}
 
ちなみにこちらを参考にしつつ透過情報を埋め込むにあたって、面倒なのでパレット0を透過色固定にしてある。
 
とりあえず上記のコードを通してから、DOBONさんところのGIFアニメを吐き出すコードを通したら、元のパレットを維持したままGIFアニメを出力できた。
 

Meltdown、Spectre、そしてJavaScript

CPUのOut Of Orderやら投機実行における脆弱性というところの仕組み(キャッシュに展開される)はなんとなくわかったのだけど、それはどうやって読み出すのだろう?JavaScriptからも可能ってのはどういうことなんだろう?
CPUのキャッシュに放り込むための投機実行のコードをJSで書けるのはわかるんだけども、

CPUキャッシュから情報を抜き出すための、FLUSH+RELOADなる方法が使われているようだ。サイドチャネルアタック(いろんな手段で観察して情報を推測したりする攻撃)らしいが。
読み取れないはずの領域のデータを添え字にしてメモリアクセスすると、
そこがキャッシュされるため、アクセス時間を正確にはかれば、データ内容が復元できる…?
 
JavaScript does not provide access to the rdtscp in-
struction, and Chrome intentionally degrades the accu-
racy of its high-resolution timer to dissuade timing at-
tacks using performance.now()[1].
However, the Web Workers feature of HTML5 makes it simple to cre-
ate a separate thread that repeatedly decrements a value
in a shared memory location [18, 32]. This approach
yielded a high-resolution timer that provided sufficient resolution
 
Javascriptからはperformance.now()といった高精度タイマーや、Workerを使うと再現でけると。
 
Jann Horn of Google Project Zero Security reported that speculative execution performed by modern CPUs could leak information through a timing side-channel attack. Microsoft Vulnerability Research extended this attack to browser JavaScript engines and demonstrated that code on a malicious web page could read data from other web sites (violating the same-origin policy) or private data from the browser itself.
Since this new class of attacks involves measuring precise time intervals, as a partial, short-term, mitigation we are disabling or reducing the precision of several time sources in Firefox. The precision of performance.now() has been reduced from 5μs to 20μs, and the SharedArrayBuffer feature has been disabled because it can be used to construct a high-resolution timer.
Mozillaはタイマーの制度を下げたのか。
SharedArrayBufferというのはWorker間でメモリを共有する仕組みで、高精度タイマーを作れちゃうのでこれをOffる対応も入ってると。
 

Webサイト リニューアル

レスポンシブルデザインとやらで、CSSFlexを使ってみた。
カードっぽいデザインでとにかくコンテンツを区切って全部表示しただけなんだけどね。ブラウザの幅を変えると表示がにゅっと動いて楽しい。

.flex {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.flexchild {
  flex-basis: 250px;
  min-width: 0;   /*こうやるとうまく文章が折り返すらしい*/
  word-wrap: break-word;

  /*孫要素の配置を制御する場合は、子要素にさらにFlex指定するとよさげ*/
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

コンテンツの中身は別管理にして、ソートとかフィルタとかできるようにしたいな。
f:id:nazenaninadesico:20180103074829p:plain
http://www.moreread.net/

さくらインターネットはWebフォントを無料でいろいろ使えるらしいので、使ってみたのだが、
f:id:nazenaninadesico:20180103074833p:plain
JSで動的に挿入したコンテンツにWebフォントが適用されてないくさい。びみょ……。
画像の「品」の字は静的コンテンツ部分に登場しなかった文字。必要な文字だけフォントを取得する仕組みらしい。

あと改めてフォントいろいろ見比べたけど、Windowsではメイリオがブラウザの標準フォントになってるので、読みやすさの観点ではそのままでも特に問題ない気がしてきて、Webフォントを使うのやめた。

MaDotPaint V1.0.0公開

MaDotPaint V1.0.0
 
ペイントツールを作ってみました。自分ツール。

 
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
_/_/ MaDotPaint
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
 
[Description]
2Dゲーム開発のお供に最適なペイントツールです。
操作手順が少なくて済むように設計されており、基本的な処理が簡単に実行できます。
表示倍率や表示位置の変更、トリミングなどをマウス操作だけで行うことができるため、高い作業効率を実現します。
また、画像サイズや、グリッド線を画面上に表示するため、確認作業にも適しています。
シンプルで軽量(たぶん)、MSペイントの代わりにどうぞ。
 
<2018/01/01> V1.0.0
First Release
 
[How to use]
左クリック:点描
左ドラッグ:矩形塗りつぶし(Shift+で線描画)
右クリック:スポイト
右ドラッグ:範囲コピー(コピー後は左クリックでペースト)
ホイール:表示倍率の変更
中ドラッグ:画像の表示位置変更(Ctrl+右ドラッグでも可)
 
画像の外側をスポイトすると、透過色を取ることができます。
パレットの各色をダブルクリックすると色を編集することができます。
パレットはEDGE形式のものを読み込むことが可能です。
 
[System Requirements]
Windows7 or later
.NET FrameWork 4.5 or later
 
[Uninstall]
Delete this folder.
 
[HP]
 
[Author]
nazenaninadesico : nazenaninadesico@gmail.com
 
[Credit]
デフォルトのパレットはこちらのMizさんのパレットを参考にさせていただきました。
 
ダウンロード先
 
なぜに?
久しぶりにゲーム開発をして、その中でさまざまな画像周りのツールにお世話になりました。しかしながら、操作性に納得がいくものがなく、また機能によって複数のアプリにまたがって利用が必要で煩雑。思えば10年以上前からそうでした。微妙にストレス。
ということで一念発起して、自分用ペイントツールを作ると決心しました。車輪の再発明感はんぱないけどしょうがないね。どこかには望みのツールがあったりするのかもだけど、見つからないんだ。
 
そして突貫で3日で作った。
とりあえずVectorに登録(10年以上使ってないアカウントを発掘)しといたけど、正月休みぽい。
 
セールスポイント

・画像サイズの数字が画面上に表示されるガイド付き。
 2Dゲームではドット単位の調整が必要なためあると便利。
・いつでもはじっこ(■のとこ)を掴んでトリミングやサイズ拡張が可能。
・マウスホイールで一瞬でズームイン、ズームアウト。
 画像の細部や全体像をぱぱっと確認できます。
・0.1倍まで縮小表示化。大きな画像の全体像をサクッと確認。
・高倍率のときはグリッド表示可能(打ち間違いを低減)。
・ミドルボタンドラッグ(又はCtrl+左ドラッグ)で画像の位置を変更可能。
 拡大中の面倒なスクロールバー操作とはお別れ!
・右クリックスポイトで、パレットまで移動しなくよい。
・範囲外をスポイトすると透過色をスポイト。
 そのまま透過色で描画すれば透過画像を生成可能。
 塗りつぶし、色置換、許容値の設定なども透過画像作成をサポート。
・右ドラッグで範囲コピー(そのまま左クリックでスタンプ可能)。
 クリップボードにも自動でコピーされます。
・左ドラッグで矩形塗りつぶし、描画効率アップ、消しゴム替わりにも。
・問答無用で32ビットPNG保存(他フォーマットは必要になれば追加予定)。
・単一ウィンドウアプリで管理が楽(MDIが苦手なだけ!)。
・MSペイント替わりにサクッと立ち上げられる軽量さ。シンプル!(低機能なだけ)
 
ターゲットは主にゲーム開発者(プログラマ)です。
グラフィッカーさんは、描画まわりが高機能なソフトを使ったほうが良いでしょう。
ゲーム開発の過程で、素材をトリミングしたり、加工したり、コードに落とす際に画像のサイズを確認したり、ちょっとした絵や仮画像を描いたり、スクリーンショット加工したり…といった場面で、高い効率性を実現します。たぶん……。加工系ツールと、ペイント系ツールの中間ぽいのかな。足りていない機能は徐々に追加していくつもり。飽きなければ!
 

アプリ公開 つづき

とりあえず全プラットフォームで公開されました。
Xamarin+CocosSharpなクロスプラットフォーム開発アプリ。
 
Android版は相変わらずダウンロードほぼゼロ。iOS版は無事公開されたけど、言語が英語になってるわ、カテゴリがアドベンチャーだわでどうしたらいいんだ。
PC版は「ふりーむ!」でレビューが2件もついてる!うれぴ!
モンスターランドやビックリマンワールドのアレなのでレトロゲーすきな方は是非プレイしてくださいまし。
 
 
iOS
 
PC版
 

 
さて、忘れないうちにまた何か作りたいものだけど。うーむ。

アプリ公開

初のAppStore申請。
①VisualStudioでReleaseビルドでipaファイルを生成する
iTunes Connectでアプリ追加したりバンドルID発行したりする
XcodeのApplicationLoaderからipaファイルをアップロードする
はじめてでよくわかっておらず、アップロードしようとするとエラーが発生。
ERROR ITMS-90161: "Invalid Provisioning Profile. ~
 
Provisioningファイルとやらが何かイマイチ理解してないけど、VisualStudioからは下記のところをDistributionにしたらなんかうまくいった気がする。

他にもアイコンの透過PNGやめーや的なエラーとかも出た。
とりあえず無事に審査待ちに。
 
Androidのほうは公開してから1日以上たってるんだけど、自分以外ダウンロード数0!
新着アプリって紹介されたりしないの?

どこからもリンクされないんじゃダウンロードされんわ。
どうすればいんだー。