public static FreeImageBitmap LoadImage(byte[] bytes) { var qntHeader = GetQntHeader(bytes); if (qntHeader == null || !qntHeader.Validate()) { return(null); } var pixels = GetQntPixels(bytes, qntHeader); byte[] alphaPixels = null; if (qntHeader.alphaSize != 0) { alphaPixels = GetQntAlpha(bytes, qntHeader); } FreeImageBitmap image = new FreeImageBitmap(qntHeader.width, qntHeader.height, qntHeader.width * 3, 24, FREE_IMAGE_TYPE.FIT_BITMAP, pixels); using (var blue = image.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_RED)) using (var red = image.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_BLUE)) { if (alphaPixels != null) { image.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_32_BPP); } image.SetChannel(blue, FREE_IMAGE_COLOR_CHANNEL.FICC_BLUE); image.SetChannel(red, FREE_IMAGE_COLOR_CHANNEL.FICC_RED); } FreeImageBitmap alpha = null; try { if (alphaPixels != null) { alpha = new FreeImageBitmap(qntHeader.width, qntHeader.height, qntHeader.width, 8, FREE_IMAGE_TYPE.FIT_BITMAP, alphaPixels); } if (alpha != null) { image.SetChannel(alpha, FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA); } } finally { if (alpha != null) { alpha.Dispose(); } } image.Comment = qntHeader.GetComment(); image.Tag = qntHeader; return(image); }
public static void SaveImage(Stream stream, FreeImageBitmap bitmap) { AjpHeader ajpHeaderFromBitmap = bitmap.Tag as AjpHeader; AjpHeader ajpHeaderFromComment = null; if (!string.IsNullOrEmpty(bitmap.Comment)) { ajpHeaderFromComment = new AjpHeader(); if (!ajpHeaderFromComment.ParseComment(bitmap.Comment)) { ajpHeaderFromComment = null; } } var ms = new MemoryStream(); var ms2 = new MemoryStream(); bitmap.Save(ms, FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_PROGRESSIVE | FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD); using (var alpha = bitmap.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA)) { if (alpha != null) { alpha.Comment = "signature = 19792, version = 2, headerSize = 64, colorDepth = 8"; Pms.SaveImage(ms2, alpha); } } AjpHeader ajpHeader = ajpHeaderFromBitmap; if (ajpHeader == null) { ajpHeader = ajpHeaderFromComment; } SaveImage(stream, ms.ToArray(), ms2.ToArray(), ajpHeader); }
public static void SaveImage(Stream stream, FreeImageBitmap bitmap) { string comment = bitmap.Comment; var pmsHeader = new PmsHeader(); bool readComment = false; if (!string.IsNullOrEmpty(comment)) { if (pmsHeader.ParseComment(comment)) { readComment = true; } } if (pmsHeader.colorDepth == 0) { pmsHeader.colorDepth = 8; } bool is8Bit = !readComment || pmsHeader.colorDepth == 8; if (!readComment) { pmsHeader.version = 1; pmsHeader.headerSize = 48; } if (pmsHeader.signature == 0) { pmsHeader.signature = 0x00004d50; } if (pmsHeader.version == 2 && pmsHeader.headerSize == 0) { pmsHeader.headerSize = 64; } if (pmsHeader.headerSize < 48) { pmsHeader.headerSize = 48; } if (pmsHeader.headerSize > 64) { pmsHeader.headerSize = 64; } pmsHeader.addressOfComment = 0; pmsHeader.height = bitmap.Height; pmsHeader.width = bitmap.Width; if (is8Bit) { if (bitmap.ColorDepth > 8) { if (bitmap.ColorDepth == 32) { bitmap.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP); } bitmap.Quantize(FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, 256); //throw new ArgumentException("image must be 8-bit"); } pmsHeader.addressOfPalette = pmsHeader.headerSize; pmsHeader.addressOfData = pmsHeader.addressOfPalette + 768; pmsHeader.colorDepth = 8; SaveHeader(stream, pmsHeader); SavePalette(stream, bitmap.Palette); SaveImageData8Bit(stream, bitmap); } else { bool hasAlphaChannel = false; var existingAlphaChannel = bitmap.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA); if (existingAlphaChannel != null) { bool allPixelsOpaque = AllPixelsOpaque(existingAlphaChannel); hasAlphaChannel = !allPixelsOpaque; } if (bitmap.ColorDepth != 32) { bitmap.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_32_BPP); } bool usingAlphaChannel = pmsHeader.shadowDepth == 8 || (pmsHeader.shadowDepth == 0 && hasAlphaChannel); pmsHeader.addressOfPalette = 0; pmsHeader.addressOfData = pmsHeader.headerSize; pmsHeader.colorDepth = 16; ushort[] image16 = new ushort[pmsHeader.width * pmsHeader.height]; byte[] image8 = null; if (usingAlphaChannel) { image8 = new byte[pmsHeader.width * pmsHeader.height]; } int o = 0; for (int y = 0; y < pmsHeader.height; y++) { var scanline = bitmap.GetScanlineFromTop32Bit(y); if (image8 == null) { for (int x = 0; x < pmsHeader.width; x++) { unchecked { int p = scanline[x]; int b = (p >> 0) & 0xFF; int g = (p >> 8) & 0xFF; int r = (p >> 16) & 0xFF; //int a = (p >> 24) & 0xFF; b = (b * 0x1F1F + 0x8000) >> 16; g = (g * 0x3F3F + 0x8000) >> 16; r = (r * 0x1F1F + 0x8000) >> 16; p = (b << 0) | (g << 5) | (r << 11); image16[o] = (ushort)p; o++; } } } else { for (int x = 0; x < pmsHeader.width; x++) { unchecked { int p = scanline[x]; int b = (p >> 0) & 0xFF; int g = (p >> 8) & 0xFF; int r = (p >> 16) & 0xFF; int a = (p >> 24) & 0xFF; b = (b * 0x1F1F + 0x8000) >> 16; g = (g * 0x3F3F + 0x8000) >> 16; r = (r * 0x1F1F + 0x8000) >> 16; p = (b << 0) | (g << 5) | (r << 11); image16[o] = (ushort)p; image8[o] = (byte)a; o++; } } } } MemoryStream ms = new MemoryStream(); SaveImageData16Bit(ms, image16, pmsHeader.width, pmsHeader.height); int imageSize = (int)ms.Length; if (usingAlphaChannel) { pmsHeader.addressOfPalette = imageSize + pmsHeader.addressOfData; } SaveHeader(stream, pmsHeader); ms.WriteTo(stream); ms.SetLength(0); if (usingAlphaChannel) { SaveImageData8Bit(stream, image8, pmsHeader.width, pmsHeader.height); } } }
/// <summary> /// Write to the given graphics, if the widget texture is not large enough it will be /// resized temporarily and then sized back. So be careful with large destrects. /// </summary> /// <param name="g"></param> /// <param name="destRect"></param> public void writeToGraphics(FreeImageBitmap g, Rectangle destRect) { bool changedSize = false; IntSize2 originalSize = new IntSize2(imageBox.Width, imageBox.Height); float cropRatio = (float)imageBox.Width / destRect.Width; Rectangle srcRect = new Rectangle(0, 0, imageBox.Width, (int)(destRect.Height * cropRatio)); //Make sure the source image is large enough, if not resize. if (originalSize.Width < srcRect.Width || originalSize.Height < srcRect.Height) { imageBox.setSize(srcRect.Width, srcRect.Height); changedSize = true; resized(); renderTexture.update(); } else if (renderOneFrame) { renderTexture.update(); } using (FreeImageBitmap fullBitmap = new FreeImageBitmap(currentTextureWidth, currentTextureHeight, BitmapFormat)) { fullBitmap.copyFromRenderTarget(renderTexture, ogreTextureFormat); //Remove alpha //BitmapDataExtensions.SetAlpha(bmpData, 255); if (srcRect.Height > fullBitmap.Height) { srcRect.Height = fullBitmap.Height; } using (FreeImageBitmap cropped = fullBitmap.Copy(srcRect)) { if (cropped != null) { cropped.Rescale(destRect.Width, destRect.Height, FREE_IMAGE_FILTER.FILTER_BILINEAR); if (ogreTextureFormat == OgrePlugin.PixelFormat.PF_X8R8G8B8) { //Use the api to set the alpha channel to 255, this makes sure we dont carry over the x8 channel from ogre using (var alpha = cropped.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA)) { alpha.FillBackground(new RGBQUAD(new FreeImageAPI.Color() { R = 255, G = 255, B = 255, A = 255 })); cropped.SetChannel(alpha, FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA); } } g.Paste(cropped, destRect.X, destRect.Y, int.MaxValue); } } } if (changedSize) { imageBox.setSize(originalSize.Width, originalSize.Height); resized(); renderTexture.update(); } }