summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla31029.cs
blob: d86ca9a16d4ade5304df7fda0208b3a7f070f7e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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;
		}
	}
}