可以在运行时在Xamarin / Android中创建一个9补丁吗?
这与this question或this question相同,但在Xamarin下工作。在那里给出答案的天真翻译会产生扭曲的九个补丁。
在下图中,原始图像位于左上角 - 以下代码对此无效。其余的应该是9补丁。似乎正在发生的事情是左上方被拉伸,而不是应该是中心。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Android.Graphics;
using Android.Graphics.Drawables;
using Java.IO;
using Android.Content.Res;
using System.IO;
using System.Drawing;
namespace Android9PatchFail
{
public class ImageCanvas : View
{
public ImageCanvas (Context context) :
base(context)
{
Initialize();
}
public ImageCanvas (Context context, IAttributeSet attrs) :
base(context, attrs)
{
Initialize();
}
public ImageCanvas (Context context, IAttributeSet attrs, int defStyle) :
base(context, attrs, defStyle)
{
Initialize();
}
void Initialize () {
this.SetBackgroundColor(Android.Graphics.Color.White);
}
public Bitmap ImageBitmap {
get {
AssetManager manager = this.Resources.Assets;
Stream stream = manager.Open("buttonb.png");
Bitmap r = BitmapFactory.DecodeStream(stream);
return r;
}
}
protected override void OnDraw (Canvas canvas) {
base.OnDraw(canvas);
Bitmap bitmap = this.ImageBitmap;
Paint paint = new Paint();
// canvas.DrawBitmap(bitmap, 20, 20, paint);
float bitmapWidth = bitmap.Width;
float bitmapHeight = bitmap.Height;
// this.DrawScaledImage(canvas, bitmap, 20, 50, new Size(100, 100));
Random rand = new Random();
double growthFactor = 0.5; rand.NextDouble();
int top = 4; // 4 12 18 14 did give output with growth of 0.174.
int left = 12;
int bottom = 18;
int right = 14;
System.Diagnostics.Debug.WriteLine("Growth is " + growthFactor);
System.Diagnostics.Debug.WriteLine("Insets are " + top + " " + left + " " + bottom + " " + right);
for (int i = 0; i < 9; i++) {
int row = i / 3;
int column = i % 3;
int width = (int) ((1 + column*growthFactor) * bitmapWidth);
float x = 20;
switch (column) {
case 1: x = 200; break;
case 2: x = 450; break;
default: break;
}
float y = 40 + 160 * row;
int height = (int) ((1 + row*growthFactor) * bitmapHeight);
Size size = new Size(width, height);
// this.DrawScaledImage(canvas, bitmap, x, y, size);
this.DrawNinePatchBitmap(canvas, bitmap, x, y, top, left, bottom, right, size);
// this.DrawNinePatchBitmap(canvas, bitmap, 200, 100, 1, 1, 5, 5, new SizeF(2 * bitmapWidth, 2 * bitmapHeight));
}
}
public void DrawScaledImage (Canvas canvas, Bitmap bitmapToStretch, float x, float y, Size requestedSize) {
Android.Graphics.Bitmap b = Android.Graphics.Bitmap.CreateScaledBitmap(bitmapToStretch, requestedSize.Width, requestedSize.Height, false);
canvas.DrawBitmap(b, x, y, null);
}
public void DrawNinePatchBitmap (Canvas canvas, Android.Graphics.Bitmap bitmapToStretch, float x, float y, int top, int left, int right, int bottom, SizeF requestedSize)
{
RectF rect = new RectF(x, y, x+requestedSize.Width, y+requestedSize.Height);
// System.Diagnostics.Debug.WriteLine("Rect is " + x + " " + y + " " + requestedSize.Width + " " + requestedSize.Height);
NinePatch npBitmap = CreateNinePatch(bitmapToStretch, top, left, bottom, right);
npBitmap.Draw(canvas, rect);
}
private NinePatch CreateNinePatch(Android.Graphics.Bitmap bitmap, int top, int left, int bottom, int right) {
MemoryStream buffer = GetMemoryStream(top, left, bottom, right);
NinePatch patch = new NinePatch(bitmap, buffer.ToArray(), "blah");
return patch;
}
private MemoryStream GetMemoryStream(int top, int left, int bottom, int right) {
//Docs check the NinePatchChunkFile
MemoryStream buffer = new MemoryStream(new byte[84]);
using (BinaryWriter writer = new BinaryWriter(buffer)) {
//was translated
writer.Write(new byte[] { 0x01 });
//divx size
writer.Write(new byte[] { 0x02 });
//divy size
writer.Write(new byte[] { 0x02 });
//color size
writer.Write(new byte[] { 0x09 });
//skip
writer.Write(0);
writer.Write(0);
//padding
writer.Write(0);
writer.Write(0);
writer.Write(0);
writer.Write(0);
//writer.Write(left);
//writer.Write(right);
//writer.Write(top);
//writer.Write(bottom);
//skip 4 bytes
writer.Write(0);
//offsets
writer.Write(left);
writer.Write(right);
writer.Write(top);
writer.Write(bottom);
//No color
writer.Write(0x00000001);
writer.Write(0x00000001);
writer.Write(0x00000001);
writer.Write(0x00000001);
writer.Write(0x00000001);
writer.Write(0x00000001);
writer.Write(0x00000001);
writer.Write(0x00000001);
writer.Write(0x00000001);
}
return buffer;
}
}
}