130 строки
3.8 KiB
C#
130 строки
3.8 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using Xamarin.Forms.CustomAttributes;
|
|
using Xamarin.Forms.Internals;
|
|
|
|
#if UITEST
|
|
using Xamarin.UITest;
|
|
using NUnit.Framework;
|
|
#endif
|
|
|
|
namespace Xamarin.Forms.Controls
|
|
{
|
|
[Preserve (AllMembers = true)]
|
|
[Issue (IssueTracker.Bugzilla, 31029, "[Windows Phone 8.1]Generating an Image via MemoryStream does not appear")]
|
|
public class Bugzilla31029 : TestContentPage // or TestMasterDetailPage, etc ...
|
|
{
|
|
protected override void Init ()
|
|
{
|
|
var generatedImage = new Image { Aspect = Aspect.AspectFit };
|
|
|
|
var btn = new Button { Text="generate" };
|
|
|
|
btn.Clicked += (sender, e) => {
|
|
var source = GenerateBmp (60, 60, Color.Red);
|
|
generatedImage.Source = source;
|
|
|
|
};
|
|
|
|
Content = new StackLayout {
|
|
Children = {
|
|
btn,
|
|
#pragma warning disable 618
|
|
new Label {Text = "GeneratedImage", Font=Font.BoldSystemFontOfSize(NamedSize.Medium)},
|
|
#pragma warning restore 618
|
|
generatedImage
|
|
},
|
|
Padding = new Thickness (0, 20, 0, 0),
|
|
VerticalOptions = LayoutOptions.StartAndExpand,
|
|
HorizontalOptions = LayoutOptions.CenterAndExpand
|
|
};
|
|
}
|
|
public ImageSource GenerateBmp (int rows, int cols, Color color)
|
|
{
|
|
BmpMaker bmpMaker = new BmpMaker (rows, cols);
|
|
//background color to white
|
|
for (int i = 0; i < rows; i++) {
|
|
for (int j = 0; j < cols; j++) {
|
|
bmpMaker.SetPixel (i, j, Color.White);
|
|
}
|
|
}
|
|
//draw a square
|
|
int marginX = rows / 10;
|
|
int marginY = cols / 10;
|
|
for (int row = marginX; row < (rows - marginX); row++) {
|
|
for (int col = marginY; col < (cols - marginY); col++) {
|
|
bmpMaker.SetPixel (row, col, color);
|
|
}
|
|
}
|
|
ImageSource resultImage = bmpMaker.Generate ();
|
|
return resultImage;
|
|
}
|
|
}
|
|
|
|
public class BmpMaker
|
|
{
|
|
const int HeaderSize = 54;
|
|
readonly byte[] _buffer;
|
|
public BmpMaker (int width, int height)
|
|
{
|
|
Width = width;
|
|
Height = height;
|
|
int numPixels = Width * Height;
|
|
int numPixelBytes = 4 * numPixels;
|
|
int fileSize = HeaderSize + numPixelBytes;
|
|
_buffer = new byte[fileSize];
|
|
// Write headers in MemoryStream and hence the buffer.
|
|
using (MemoryStream memoryStream = new MemoryStream (_buffer)) {
|
|
using (BinaryWriter writer = new BinaryWriter (memoryStream, Encoding.UTF8)) {
|
|
// Construct BMP header (14 bytes).
|
|
writer.Write (new char[] { 'B', 'M' }); // Signature
|
|
writer.Write (fileSize); // File size
|
|
writer.Write ((short) 0); // Reserved
|
|
writer.Write ((short) 0); // Reserved
|
|
writer.Write (HeaderSize); // Offset to pixels
|
|
// Construct BitmapInfoHeader (40 bytes).
|
|
writer.Write (40); // Header size
|
|
writer.Write (Width); // Pixel width
|
|
writer.Write (Height); // Pixel height
|
|
writer.Write ((short) 1); // Planes
|
|
writer.Write ((short) 32); // Bits per pixel
|
|
writer.Write (0); // Compression
|
|
writer.Write (numPixelBytes); // Image size in bytes
|
|
writer.Write (0); // X pixels per meter
|
|
writer.Write (0); // Y pixels per meter
|
|
writer.Write (0); // Number colors in color table
|
|
writer.Write (0); // Important color count
|
|
}
|
|
}
|
|
}
|
|
|
|
public int Width { get; private set; }
|
|
public int Height { get; private set; }
|
|
|
|
public void SetPixel (int row, int col, Color color)
|
|
{
|
|
SetPixel (row, col, (int) (255 * color.R),
|
|
(int) (255 * color.G),
|
|
(int) (255 * color.B),
|
|
(int) (255 * color.A));
|
|
}
|
|
|
|
public void SetPixel (int row, int col, int r, int g, int b, int a = 255)
|
|
{
|
|
int index = (row * Width + col) * 4 + HeaderSize;
|
|
_buffer[index + 0] = (byte) b;
|
|
_buffer[index + 1] = (byte) g;
|
|
_buffer[index + 2] = (byte) r;
|
|
_buffer[index + 3] = (byte) a;
|
|
}
|
|
|
|
public ImageSource Generate ()
|
|
{
|
|
Stream memoryStream = new MemoryStream (_buffer);
|
|
ImageSource imageSource = ImageSource.FromStream (() => { return memoryStream; });
|
|
return imageSource;
|
|
}
|
|
}
|
|
}
|