kolya5544

RUSSIA

Jul 29th, 2022
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.68 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using BMPC = BMP;
  5.  
  6. class MainClass {
  7. static void Main() {
  8. BMPC bmpc = new BMPC();
  9. bmpc.matrix = new int[512,512];
  10. int val = 0xFFFFFF;
  11. for (int y = 0; y<512; y++){
  12. if (y > 168) val = 0x0000FF;
  13. if (y > 338) val = 0xFF0000;
  14. for(int x = 0; x < 512; x++) {
  15. bmpc.matrix[x, y] = val;
  16. }
  17. }
  18. byte[] result = bmpc.GetContents();
  19. Console.WriteLine($"data:image/png;base64,{Convert.ToBase64String(result)}");
  20. }
  21. }
  22.  
  23. public class BMP
  24. {
  25. public string ArbHeader { get; set; }
  26. public int[,] matrix { get {
  27. return _matrix;
  28. } set
  29. {
  30. _matrix = value;
  31. _W = value.GetLength(0);
  32. _H = value.GetLength(1);
  33. }
  34. }
  35. public int W { get { return _W; } } public int H { get { return _H; } }
  36.  
  37. int _W, _H;
  38. int[,] _matrix;
  39. MemoryStream Contents;
  40. public bool built = false;
  41.  
  42. public void Save(string filename)
  43. {
  44. File.WriteAllBytes(filename, GetContents());
  45. }
  46.  
  47. public byte[] GetPicData()
  48. {
  49. BuildBMP();
  50. Contents.Position = 54;
  51. var toRead = Contents.Length - Contents.Position;
  52. byte[] arr = new byte[toRead];
  53. Contents.Read(arr, 0, (int)toRead);
  54. return arr;
  55. }
  56.  
  57. public void SetPicData(byte[] data, int width, int height)
  58. {
  59. matrix = new int[width, height];
  60. MemoryStream ms = new MemoryStream(data);
  61. for (int y = height - 1; y >= 0; y--)
  62. {
  63. int paddingLen = W % 4;
  64. byte[] toRead = new byte[width * 3 + paddingLen];
  65. ms.Read(toRead, 0, toRead.Length);
  66. for (int i = 0; i<width; i++)
  67. {
  68. byte B = toRead[i * 3];
  69. byte G = toRead[i * 3 + 1];
  70. byte R = toRead[i * 3 + 2];
  71. matrix[i, y] = R * 0x10000 + G * 0x100 + B;
  72. }
  73. }
  74. }
  75.  
  76. public byte[] GetContents()
  77. {
  78. BuildBMP();
  79. Contents.Position = 0;
  80. byte[] arr = Contents.ToArray();
  81. return arr;
  82. }
  83.  
  84. private void BuildBMP()
  85. {
  86. Contents = new MemoryStream();
  87. Contents.Position = 0;
  88.  
  89. if (matrix == null || matrix.GetLength(0) < 1 || matrix.GetLength(1) < 1) throw new ArgumentException("BMP contents are empty. Nothing to build");
  90.  
  91. Baker.BMHeader(Contents);
  92. int pixelAmount = W * H;
  93. int fileSize = pixelAmount * 3 + H * (W % 4) + 54;
  94. Baker.FileSizeHeader(Contents, fileSize);
  95. Baker.ArbitraryHeader(Contents, ArbHeader == null ? new byte[] { 0x00, 0x00, 0x00, 0x00 } : Encoding.UTF8.GetBytes(ArbHeader));
  96. Baker.PixelOffsetHeader(Contents);
  97. Baker.DIB(Contents, W, H);
  98.  
  99. int paddingLen = W % 4;
  100. for (int y = H - 1; y >= 0; y--)
  101. {
  102. for (int x = 0; x < W; x++)
  103. {
  104. int RGB = matrix[x, y];
  105. byte R = (byte)((RGB >> 16) & 0xff);
  106. byte G = (byte)((RGB >> 8) & 0xff);
  107. byte B = (byte)((RGB >> 0) & 0xff);
  108. Contents.Write(new byte[] { B, G, R }, 0, 3);
  109. }
  110. Contents.Write(new byte[paddingLen], 0, paddingLen);
  111. }
  112.  
  113. built = true;
  114. }
  115.  
  116. #region Initializers
  117. /// <summary>
  118. /// Initializes a BMP class.
  119. /// </summary>
  120. public BMP()
  121. {
  122.  
  123. }
  124. #endregion
  125. }
  126.  
  127. /// <summary>
  128. /// A class managing 24-bit BMP building
  129. /// </summary>
  130. internal static class Baker
  131. {
  132. #region Static data (Headers)
  133. private readonly static byte[] IDField = { 0x42, 0x4D }; //"BM". BMP magic.
  134. private readonly static byte[] DataOffset = { 0x36, 0x00, 0x00, 0x00 }; //54. Shows the location of pixel data.
  135. private readonly static byte[] DIBNumber = { 0x28, 0x00, 0x00, 0x00 }; //40. DIB header size in bytes.
  136. private readonly static byte[] DIB_MagicBytes_1 = {
  137. 0x01, 0x00,//plane amount.
  138. 0x18, 0x00,//Bits per pixel.
  139. 0x00, 0x00, 0x00, 0x00 //zero compression
  140. };
  141. private static readonly byte[] DIB_MagicBytes_2 =
  142. {
  143. 0x13, 0x0B, 0x00, 0x00, //Printing details =======
  144. 0x13, 0x0B, 0x00, 0x00, //========================
  145. 0x00, 0x00, 0x00, 0x00, //colors amount
  146. 0x00, 0x00, 0x00, 0x00 // all colors are important
  147. };
  148. #endregion
  149.  
  150. /// <summary>
  151. /// Writes a "BM" Header to the Stream.
  152. /// </summary>
  153. /// <param name="s">Stream to write the header to</param>
  154. public static void BMHeader(Stream s)
  155. {
  156. s.Write(IDField, 0, IDField.Length);
  157. }
  158. /// <summary>
  159. /// Adds BMP size header to the file.
  160. /// </summary>
  161. /// <param name="s">Stream to write the header to</param>
  162. /// <param name="BMPSize">Size of a BMP file</param>
  163. public static void FileSizeHeader(Stream s, int BMPSize)
  164. {
  165. byte[] Bytes = BitConverter.GetBytes(BMPSize);
  166. s.Write(Bytes, 0, Bytes.Length);
  167. }
  168. /// <summary>
  169. /// Adds program-specific unused value to the file. (Can be anything)
  170. /// </summary>
  171. /// <param name="s">Stream to write the header to</param>
  172. /// <param name="header">String header representation</param>
  173. public static void ArbitraryHeader(Stream s, string header)
  174. {
  175. ArbitraryHeader(s, Encoding.UTF8.GetBytes(header));
  176. }
  177.  
  178. /// <summary>
  179. /// Adds program-specific unused value to the file. (Can be anything)
  180. /// </summary>
  181. /// <param name="s">Stream to write the header to</param>
  182. /// <param name="header">Byte array to be added</param>
  183. public static void ArbitraryHeader(Stream s, byte[] header)
  184. {
  185. if (header.Length == 4)
  186. {
  187. s.Write(header, 0, 4);
  188. }
  189. else
  190. {
  191. throw new ArgumentException("Header length should be 4 bytes.");
  192. }
  193. }
  194. /// <summary>
  195. /// Writes offset to pixel array to the file.
  196. /// </summary>
  197. /// <param name="s">Stream to write pixel offset to</param>
  198. public static void PixelOffsetHeader(Stream s)
  199. {
  200. s.Write(DataOffset, 0, DataOffset.Length);
  201. }
  202. /// <summary>
  203. /// Manages DIB header creation
  204. /// </summary>
  205. /// <param name="s">Stream to write DIB header to</param>
  206. /// <param name="w">Width of the BMP</param>
  207. /// <param name="h">Height of the BMP</param>
  208. public static void DIB(Stream s, int w, int h)
  209. {
  210. s.Write(DIBNumber, 0, DIBNumber.Length);
  211. byte[] wBytes = BitConverter.GetBytes(w);
  212. byte[] hBytes = BitConverter.GetBytes(h);
  213. s.Write(wBytes, 0, wBytes.Length);
  214. s.Write(hBytes, 0, hBytes.Length);
  215. s.Write(DIB_MagicBytes_1, 0, DIB_MagicBytes_1.Length);
  216. int padding = w % 4;
  217. byte[] RawBitmapSize = BitConverter.GetBytes((w * 3 + padding) * h);
  218. s.Write(RawBitmapSize, 0, RawBitmapSize.Length);
  219. s.Write(DIB_MagicBytes_2, 0, DIB_MagicBytes_2.Length);
  220. }
  221. }
Add Comment
Please, Sign In to add comment