2018年10月09日

SharpDX + DirectX9でスクリーンショット取得

SharpDXつかってC#でDirectX9使ってる時にスクリーンショットを取る必要が出たので覚書。
// ★事前準備。
// デフォルトレンダリングターゲットのSurfaceを取得
Surface s = device.GetRenderTarget(0);
SurfaceDescription sd = s.Description;

// 保存用のSurfaceと、コピー領域指定用用のRectangleを生成。
Surface saveSurface = Surface.CreateOffscreenPlain(device, sd.Width, sd.Height, sd.Format, Pool.SystemMemory);
Rectangle rect = Rectangle(0, 0, sd.Width, sd.Height);

// ★保存処理実施
device.GetRenderTargetData(s, saveSurface);
DataRectangle dr = _SaveView.LockRectangle(LockFlags.ReadOnly);
byte[] buf = new byte[dr.Pitch * Height];

// DirectXのバックバッファから一時バッファへコピー(1)
Marshal.Copy(dr.DataPointer, buf, 0, buf.Length);
_SaveView.UnlockRectangle();

try {
using(Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb)){
// 一時バッファからBitmapのデータ領域へコピー(2)
BitmapData bd = _SaveBmp.LockBits(_SaveRect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(buf, 0, bd.Scan0, buf.Length);
bmp.UnlockBits(bd);
// BitmapをJPEGで保存
bmp.Save(path, ImageFormat.Jpeg);
}
}
catch(Exception ex) {
// エラーログ出すとか
}

(1)と(2)の処理を一度でできるといいけど、
Marshal.Copyでsrc、dstともIntPtrで指定できるやつを見つけられていない・・・
なにかしら他の方法で一発で行けるかな・・・?

なににせよ、とりあえずスクリーンショットはとれるようになったし、毎フレーム実施するわけでもないので、若干重くなってもいいや、という感じでとりあえずはこれでOKとしておく・・・。
タグ:DirectX
posted by ぱぱぷた at 21:58| Comment(0) | おしごと

2018年08月24日

Androidのオーバーレイ表示がOreoで変わりすぎ

Androidの画面レイヤー構成がOreoから大幅に変わったことは周知の事実だけど、画面をロックするアプリが困ったことになった。

仕様の変更で、使えなくなったレイヤーは以下の通り。
TYPE_PHONE
TYPE_PRIORITY_PHONE
TYPE_SYSTEM_ALERT
TYPE_SYSTEM_OVERLAY
TYPE_SYSTEM_ERROR

で、代わりに「TYPE_APPLICATION_OVERLAY」を使ってね。という事らしい。

試しに今までNougat(Android 7.0)で問題なく動作していた、現在作成中の赤ちゃん対策ロックアプリをそのまま動かしてみると、ロック画面表示でException発生・・・。
android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@a5b5602 -- permission denied for window type 2010

ナビゲーションバーのボタンを抑止するため、ロック用のレイヤーを「TYPE_SYSTEM_ERROR」に表示していたけど、Oreoからは使っちゃいけないレイヤーになってしまいました。
アプリの設定で、「重ねて表示する」許可をONにしても、当然ダメ。

仕方がないのでロックレイヤーのパラメータを以下に変更。
_prms = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
// ★以前のバージョン
// WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
// ★修正後
((Build.VERSION.SDK_INT >= 26) ?
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR),
// ★ココマデ
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR |
WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION |
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS |
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED |
WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);

コレでなんとかロック画面は出せたけど、画面上下隅からのスワイプとか、ホームボタンが抑止できなくなってしまいました。

他に公開されているロックアプリも試してみたけど、やはり同様にナビゲーションバーはロックできず、全画面表示とか、ナビゲーションバー非表示にして、スワイプで表示されたら直後に非表示にさせるなど、苦肉の方法をとっているみたい。

コレ、Oreo以降はベンダー以外ちゃんとしたロックアプリ作れないんじゃないだろうか?
あるいはおいらが調査不足なだけ・・・?

赤ちゃん、間違いなく画面外からのスワイプ・・・するよ・・・。
posted by ぱぱぷた at 13:20| Comment(0) | おしごと

2018年08月07日

Androidのボタンの影をstyle定義で消す方法覚書

androidのアプリでButtonに影がついてしまうー、という件で調べてみたら、解決策が色々出てはきたけど、なんかこー、思ってたんと違う・・・というのが多かったので、覚書。

やりたいことは、style.xmlで定義したボタンの共通定義で、影がつかないように、ということだったのだが、以下の方法にたどり着きました。

<style name="MyBorderlessButton" parent="@style/Widget.AppCompat.Button.Borderless">
<item name="android:background">@drawable/radius_button</item>
<item name="android:textSize">14sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/White</item>
</style>

parentに@style/Widget.AppCompat.Button.Borderless
を設定するということで解決。

これにたどり着くまでには、だいたいレイアウトファイル(activity_hogehoge.xml)のなかで、以下のような設定すればよいよー、と教えてくれるサイト様が多かったですが、styleでやりたい場合は使えないみたい。

<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/hogehoge_button"
android:text="なにがしかの文字列"
android:textSize="14dp"
style="?android:attr/borderlessButtonStyle"
android:id="@+id/hogehogeButton" />


あとは、android-21/data/res/values/styles_material.xmlの定義を差し替えてしまうという荒業?を教えて下さるサイトもあったりしましたが、そこまでやりたくない(モノグサ)。

とりあえず、簡単にできる方法が見つかってよかった・・・探す手間はかかったけど、今後は困らないハズ。
posted by ぱぱぷた at 17:20| Comment(0) | おしごと