アプリ置き場

アプリ置き場

http://www.moreread.net/

C# RARアーカイブから画像を読み込む

① nugetでSharpCompressをインストール

f:id:nazenaninadesico:20180909014756p:plain

② usingする

using SharpCompress.Archives;

③画像を読み込む
IArchive rar = ArchiveFactory.Open(path);
foreach (var e in rar.Entries)
{
     using (Stream s =e.OpenEntryStream())
     {
         Image img =Image.FromStream(s);
     }
}
rar.Dispose();

リタイアシミュレータ

逃げ切り計算機を使わせていただいて妄想が捗っていたのですが、細かい設定がしたかったり、グラフで見たかったり、結果を保存したかったり、等々があったのでシミュレータを作りました。
早期リタイア、アーリーリタイア、セミリタイアのための資産運用シミュレーションです。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

BitMex 価格の取得

ccxtでBitMexのfetch_tickerが403になる。
下記で価格はとれた。
サーバーが直るのか、APIが禁止でccxtが更新されるのかわからんけど、暫定でとりあえずbotの動作再開。
import urllib
 
data = json.loads(ret.decode("utf8"))
 
return data["result"]["price"]

Amazon Echo スキル開発

審査かなりきびしい。何度めだかわからない申請してようやく通った。
とりあえず習作として「目隠し○×ゲーム」というのを作ってみました。
 
下記のサイトに紹介が。
//動画があったので再生したらうちのAlexaが反応するっていう。。ピザ注文テロとか発生しそう。
 
数字で座標を指定して○×を配置するルールなのだけど、申請のリジェクト理由の一つに、ユーザーは「真ん中」とかいうから!ちゃんと対応して!みたいなのがあって、細かいなぁと思った。まだ登録されてるアプリが少ないけど、審査厳しくて弾かれまくってるんじゃなかろうか。
 
あとDQX用にやいばくだきタイマ―つくったら商標ブランドがうんたらでダメっていわれた。無念。

echo dot 例外処理は?

ようやくとどいたー。結構いい精度で聞き取ってくれる。


そして、チュートリアルに言われるがまま、ぽちぽちクリックしてたらスキルつくれた。
 
無言だったときとか、聞き取れなかった場合などの処理がよくわからなかったが、UnhandledやSessionEndedRequestで拾えるらしい。ちなみにaskは8秒経過で次のメッセージ、さらに8秒経過でセッションが切れてSessionEndedRequestだそうな。
 
var handlers = {
    'LaunchRequest': function () {
        this.emit(':ask', text, text2);
    },
  ~~略~~
    Unhandled: function() {
        this.emit(':ask', ”ぱーどぅん?”, "わっと?");
    },
    SessionEndedRequest: function() {}
};

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アニメを出力できた。