public BasicImage(byte[] data, BitMapFileHeader fileHeader, BitMapInfoHeader infoHeader) { Util.CheckSizes(fileHeader, infoHeader, data.Length); width = infoHeader.BiWidth; actualWidth = ((infoHeader.BiBitCount * width + 31) / 32) * 4; height = infoHeader.BiHeight; offset = fileHeader.BfOffBits; bytesPerPixel = infoHeader.BiBitCount / 8; this.data = data; }
internal static void CheckSizes(BitMapFileHeader fileHeader, BitMapInfoHeader infoHeader, int actualSize) { if (infoHeader.BiBitCount != 24 && infoHeader.BiBitCount != 32) { throw new ArgumentException("Error: nuber of bits per pixel other than 24 and 32 are not supported."); } if (fileHeader.BfSize != actualSize || infoHeader.BiWidth * infoHeader.BiHeight * (infoHeader.BiBitCount / 8) > fileHeader.BfSize) { throw new ArgumentException("Error: file contents don't match declared size."); } }
internal static void HandleBitMapFileHeader(byte[] bytes, out BitMapFileHeader header) { header = new BitMapFileHeader(); if (bytes[0] == 0x42 && bytes[1] == 0x4D) { header.BfSize = (uint)((bytes[5] << 24) + (bytes[4] << 16) + (bytes[3] << 8) + bytes[2]); header.BfOffBits = (uint)((bytes[13] << 24) + (bytes[12] << 16) + (bytes[11] << 8) + bytes[10]); } else if (bytes[0] == 0x4D && bytes[1] == 0x42) { throw new ArgumentException("Big-endian images are not supported."); } else { throw new ArgumentException("Source is not a valid bmp file."); } }
internal static void ApplyGreyen( byte[] source, byte[] destination, BitMapFileHeader fileHeader, BitMapInfoHeader infoHeader) { var sourceImage = new BasicImage(source, fileHeader, infoHeader); var destinationImage = new BasicImage(destination, fileHeader, infoHeader); for (int i = 0; i < infoHeader.BiHeight; i++) { for (int j = 0; j < infoHeader.BiWidth; j++) { byte average = ToByte(sourceImage[i, j, ColourPart.Red] * RedLuminance + sourceImage[i, j, ColourPart.Green] * GreenLuminance + sourceImage[i, j, ColourPart.Blue] * BlueLuminance); destinationImage[i, j, ColourPart.Red] = average; destinationImage[i, j, ColourPart.Green] = average; destinationImage[i, j, ColourPart.Blue] = average; } } }
internal static void ApplyKernel( byte[] source, byte[] destination, double[][] kernel, BitMapFileHeader fileHeader, BitMapInfoHeader infoHeader) { var sourceImage = new BasicImage(source, fileHeader, infoHeader); var destinationImage = new BasicImage(destination, fileHeader, infoHeader); var lastPart = ColourPart.Alpha; if (infoHeader.BiBitCount == 24) { lastPart = ColourPart.Blue; } for (int i = 0; i < infoHeader.BiHeight; i++) { for (int j = 0; j < infoHeader.BiWidth; j++) { for (var part = ColourPart.Red; part <= lastPart; part++) { double value = 0; for (int row = 0; row < 3; row++) { for (int column = 0; column < 3; column++) { value += kernel[row][column] * sourceImage[i - 1 + row, j - 1 + column, part]; } } destinationImage[i, j, part] = AbsToByte(value); } } } }