public void Create(int Width, int Height, GR.Drawing.PixelFormat PixelFormat) { Clear(); m_Width = Width; m_Height = Height; m_PixelFormat = PixelFormat; int bytesPerLine = BitsPerPixel * Width / 8; m_ImageData.Resize((uint)(bytesPerLine * Height)); switch (m_PixelFormat) { case GR.Drawing.PixelFormat.Format1bppIndexed: m_PaletteData = new GR.Memory.ByteBuffer(2 * 3); break; case GR.Drawing.PixelFormat.Format4bppIndexed: m_PaletteData = new GR.Memory.ByteBuffer(16 * 3); break; case GR.Drawing.PixelFormat.Format8bppIndexed: m_PaletteData = new GR.Memory.ByteBuffer(256 * 3); break; case GR.Drawing.PixelFormat.Format16bppRgb555: case GR.Drawing.PixelFormat.Format24bppRgb: case GR.Drawing.PixelFormat.Format32bppArgb: case GR.Drawing.PixelFormat.Format32bppRgb: break; default: throw new NotSupportedException("Pixelformat " + PixelFormat + " not supported"); } }
public GR.Memory.ByteBuffer CreateHDIBAsBuffer() { GR.Memory.ByteBuffer result = new GR.Memory.ByteBuffer(); BITMAPINFOHEADER bi = new BITMAPINFOHEADER(); int dwLen; IntPtr hDIB; if ((BitsPerPixel != 1) && (BitsPerPixel != 2) && (BitsPerPixel != 4) && (BitsPerPixel != 8) && (BitsPerPixel != 15) && (BitsPerPixel != 16) && (BitsPerPixel != 24) && (BitsPerPixel != 32)) { // not supported depth return(null); } bi.biSize = System.Runtime.InteropServices.Marshal.SizeOf(bi); bi.biWidth = Width; bi.biHeight = Height; bi.biPlanes = 1; bi.biBitCount = (short)BitsPerPixel; if (bi.biBitCount == 15) { bi.biBitCount = 16; } bi.biCompression = (int)BitmapCompression.BI_RGB; bi.biSizeImage = (int)(((((uint)bi.biWidth * bi.biBitCount) + 31) / 32 * 4) * bi.biHeight); bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // calculate size of memory block required to store BITMAPINFO dwLen = bi.biSize + PaletteSize(bi) + bi.biSizeImage; hDIB = System.Runtime.InteropServices.Marshal.AllocHGlobal(dwLen); if (hDIB == IntPtr.Zero) { // uh oh return(null); } unsafe { // lock memory block and get pointer to it BITMAPINFOHEADER *lpbi = (BITMAPINFOHEADER *)GlobalLock(hDIB); // Daten in den Puffer kopieren *lpbi = bi; // Bild-Daten kopieren switch (bi.biBitCount) { case 1: { // Palette in DC setzen if (PaletteEntryCount > 0) { RGBQUAD *bmiColor; bmiColor = (RGBQUAD *)((byte *)lpbi + lpbi->biSize); for (int i = 0; i < 2; i++) { bmiColor[i].rgbRed = PaletteRed(i); bmiColor[i].rgbGreen = PaletteGreen(i); bmiColor[i].rgbBlue = PaletteBlue(i); bmiColor[i].rgbReserved = 0; } } byte *pData = (byte *)lpbi + lpbi->biSize + PaletteSize(bi); int iLO = Width / 8; if ((Width & 7) != 0) { iLO++; } if ((iLO % 4) != 0) { iLO += 4 - (iLO % 4); } /* * GR::Graphic::ContextDescriptor cdImage( Image ); * GR::Graphic::ContextDescriptor cdTarget; * * cdTarget.Attach( cdImage.Width(), cdImage.Height(), iLO, cdImage.ImageFormat(), pData ); * * for ( int j = 0; j < Image.Height(); j++ ) * { * cdTarget.HLine( 0, cdTarget.Width() - 1, j, 1 ); * cdTarget.HLine( 1, cdTarget.Width() - 2, j, 0 ); * }*/ } break; case 4: { // Palette in DC setzen if (PaletteEntryCount > 0) { RGBQUAD *bmiColor = (RGBQUAD *)((byte *)lpbi + lpbi->biSize); for (int i = 0; i < 16; i++) { bmiColor[i].rgbRed = PaletteRed(i); bmiColor[i].rgbGreen = PaletteGreen(i); bmiColor[i].rgbBlue = PaletteBlue(i); bmiColor[i].rgbReserved = 0; } } byte *pData = (byte *)lpbi + lpbi->biSize + PaletteSize(bi); int iLO = Width / 2; if ((Width & 1) != 0) { iLO++; } if ((iLO % 4) != 0) { iLO += 4 - (iLO % 4); } for (int j = 0; j < Height; j++) { for (int i = 0; i < Width; i++) { ((byte *)pData)[i + (Height - j - 1) * iLO] = (byte)GetPixel(i, j); } } /* * GR::Graphic::ContextDescriptor cdImage( Image ); * GR::Graphic::ContextDescriptor cdTarget; * * cdTarget.Attach( cdImage.Width(), cdImage.Height(), iLO, cdImage.ImageFormat(), pData ); * * for ( int j = 0; j < Image.Height(); j++ ) * { * cdImage.CopyLine( 0, j, cdImage.Width(), 0, cdImage.Height() - j - 1, &cdTarget ); * }*/ } break; case 8: { // Palette in DC setzen if (PaletteEntryCount > 0) { RGBQUAD *bmiColor; bmiColor = (RGBQUAD *)((byte *)lpbi + lpbi->biSize); for (int i = 0; i < 256; i++) { bmiColor[i].rgbRed = PaletteRed(i); bmiColor[i].rgbGreen = PaletteGreen(i); bmiColor[i].rgbBlue = PaletteBlue(i); bmiColor[i].rgbReserved = 0; } } byte *pData = (byte *)lpbi + lpbi->biSize + PaletteSize(bi); int iLO = Width; if ((iLO % 4) != 0) { iLO += 4 - (iLO % 4); } for (int j = 0; j < Height; j++) { for (int i = 0; i < Width; i++) { ((byte *)pData)[i + (Height - j - 1) * iLO] = (byte)GetPixel(i, j); } } } break; case 16: { byte *pData = (byte *)lpbi + lpbi->biSize + PaletteSize(bi); int iLO = Width * 2; if ((iLO % 4) != 0) { iLO += 4 - (iLO % 4); } for (int j = 0; j < Height; j++) { for (int i = 0; i < Width; i++) { ((ushort *)pData)[i + (Height - j - 1) * iLO / 2] = (ushort)GetPixel(i, j); } } } break; /* * case 24: * { * byte *pData = (byte*)lpbi + lpbi->biSize + PaletteSize( bi ); * * int iLO = Width * 3; * if ( ( iLO % 4 ) != 0 ) * { * iLO += 4 - ( iLO % 4 ); * } * for ( int j = 0; j < Height; j++ ) * { * for ( int i = 0; i < Width; i++ ) * { * ( (byte*)pData )[3 * i + ( Height - j - 1 ) * iLO] = (byte)*( (byte*)Image.Data() + 3 * ( i + j * Image.Width() ) ); * ( (byte*)pData )[3 * i + ( Height - j - 1 ) * iLO + 1] = (byte)*( (byte*)Image.Data() + 3 * ( i + j * Image.Width() ) + 1 ); * ( (byte*)pData )[3 * i + ( Height - j - 1 ) * iLO + 2] = (byte)*( (byte*)Image.Data() + 3 * ( i + j * Image.Width() ) + 2 ); * } * } * } * break;*/ case 32: { byte *pData = (byte *)lpbi + lpbi->biSize + PaletteSize(bi); int iLO = Width; for (int j = 0; j < Height; j++) { for (int i = 0; i < Width; i++) { ((uint *)pData)[i + (Height - j - 1) * iLO] = GetPixel(i, j); } } } break; default: Debug.Log("CreateHDIBAsBuffer unsupported depth " + bi.biBitCount); break; } byte *pDIBData = (byte *)lpbi; result.Resize((uint)(bi.biSize + PaletteSize(bi) + bi.biSizeImage)); System.Runtime.InteropServices.Marshal.Copy(new IntPtr(pDIBData), result.Data(), 0, (int)result.Length); GlobalUnlock(hDIB); System.Runtime.InteropServices.Marshal.FreeHGlobal(hDIB); } return(result); }