private unsafe void ResetRotateBitmap(FreeImageBitmap fib) { ((int *)fib.GetScanlinePointer(0))[0] = 0x00000001; ((int *)fib.GetScanlinePointer(0))[1] = 0x00000002; ((int *)fib.GetScanlinePointer(1))[0] = 0x00000003; ((int *)fib.GetScanlinePointer(1))[1] = 0x00000004; }
public unsafe void GetRotatedInstance() { using (FreeImageBitmap fib = new FreeImageBitmap(2, 2, PixelFormat.Format32bppArgb)) { ((int *)fib.GetScanlinePointer(0))[0] = 0x1; ((int *)fib.GetScanlinePointer(0))[1] = 0x2; ((int *)fib.GetScanlinePointer(1))[0] = 0x3; ((int *)fib.GetScanlinePointer(1))[1] = 0x4; using (FreeImageBitmap conv = fib.GetRotatedInstance(90d)) { Assert.IsNotNull(conv); Assert.AreEqual(((int *)conv.GetScanlinePointer(0))[0], 0x3); Assert.AreEqual(((int *)conv.GetScanlinePointer(0))[1], 0x1); Assert.AreEqual(((int *)conv.GetScanlinePointer(1))[0], 0x4); Assert.AreEqual(((int *)conv.GetScanlinePointer(1))[1], 0x2); } } }
private FreeImageBitmap DrawTiles(Metafile metafile, Transparency transparency) { // http://stackoverflow.com/a/503201/270712 by rjmunro int numTiles = (OriginalHeight - 1) / Height + 1; int percentCompletedStep = 100 / (numTiles * 2 + 1); Logger.Info("Preparing to draw {0} tiles...", numTiles); FreeImageBitmap f = new FreeImageBitmap(Width, OriginalHeight, PixelFormat.Format32bppArgb); Graphics g = CreateGraphics(transparency); int scanLineSize = Width * 4; // must align with 32 bits; with RGBA this is always the case Logger.Info("Scan line size: {0:0.0} kB", scanLineSize / 1024); int currentLine = 0; int metafileHeight = metafile.Height; int metafileWidth = metafile.Width; Rectangle destinationRect = new Rectangle( Width, Height, 0, 0); while (currentLine < OriginalHeight && !_cancelled) { Logger.Info("Drawing tile starting at y={0}...", currentLine); PercentCompleted += percentCompletedStep; int currentTileHeight = Math.Min(Height, OriginalHeight - currentLine); g.Clear(Color.Transparent); Rectangle sourceRect = new Rectangle( 0, metafileHeight * currentLine / OriginalHeight, metafileWidth, metafileHeight * Height / OriginalHeight); Logger.Debug("Source rect: {0}; destination rect: {1}", sourceRect, destinationRect); g.DrawImage(metafile, destinationRect, sourceRect, GraphicsUnit.Pixel); PercentCompleted += percentCompletedStep; IntPtr scanlinePointer = f.GetScanlinePointer(currentLine); BitmapData bitmapData = _bitmap.LockBits( new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); CopyMemory(scanlinePointer, bitmapData.Scan0, Convert.ToUInt32(bitmapData.Stride * currentTileHeight)); _bitmap.UnlockBits(bitmapData); currentLine += currentTileHeight; } g.Dispose(); if (!_cancelled) { Logger.Info("Flipping FreeImage vertically."); PercentCompleted += percentCompletedStep; f.RotateFlip(RotateFlipType.RotateNoneFlipY); return(f); } else { Logger.Info("Drawing of tiles was cancelled, returning null"); return(null); } }
private unsafe FreeImageBitmap createImageFromChannels(FreeImageBitmap redSrc, Channel redSrcChannel, FreeImageBitmap greenSrc, Channel greenSrcChannel, FreeImageBitmap blueSrc, Channel blueSrcChannel) { if (redSrc.Width != greenSrc.Width || greenSrc.Width != blueSrc.Width) { //Do an error } int width = redSrc.Width; int height = redSrc.Height; FreeImageBitmap retVal = new FreeImageBitmap(width, height, FreeImageAPI.PixelFormat.Format24bppRgb); int redWalk = redSrc.ColorDepth / 8; int greenWalk = greenSrc.ColorDepth / 8; int blueWalk = blueSrc.ColorDepth / 8; int retWalk = retVal.ColorDepth / 8; int redChannel = getIndexForChannel(redSrcChannel); int greenChannel = getIndexForChannel(greenSrcChannel); int blueChannel = getIndexForChannel(blueSrcChannel); for (int y = 0; y < height; ++y) { var redScanline = (byte *)redSrc.GetScanlinePointer(y).ToPointer(); var greenScanline = (byte *)greenSrc.GetScanlinePointer(y).ToPointer(); var blueScanline = (byte *)blueSrc.GetScanlinePointer(y).ToPointer(); var retScanline = (byte *)retVal.GetScanlinePointer(y).ToPointer(); for (int x = 0; x < width; ++x) { retScanline[FreeImage.FI_RGBA_BLUE] = blueScanline[blueChannel]; retScanline[FreeImage.FI_RGBA_GREEN] = greenScanline[greenChannel]; retScanline[FreeImage.FI_RGBA_RED] = redScanline[redChannel]; redScanline += redWalk; greenScanline += greenWalk; blueScanline += blueWalk; retScanline += retWalk; } } return(retVal); }
private static unsafe FreeImageBitmap combineImages(FreeImageBitmap alphaSrc, Channel alphaSrcChannel, FreeImageBitmap redSrc, Channel redSrcChannel, FreeImageBitmap greenSrc, Channel greenSrcChannel, FreeImageBitmap blueSrc, Channel blueSrcChannel, FreeImageBitmap combined) { int width = combined.Width; int height = combined.Height; int alphaWalk = alphaSrc.ColorDepth / 8; int redWalk = redSrc.ColorDepth / 8; int greenWalk = greenSrc.ColorDepth / 8; int blueWalk = blueSrc.ColorDepth / 8; int combinedWalk = combined.ColorDepth / 8; int alphaChannel = getIndexForChannel(alphaSrcChannel); int redChannel = getIndexForChannel(redSrcChannel); int greenChannel = getIndexForChannel(greenSrcChannel); int blueChannel = getIndexForChannel(blueSrcChannel); for (int y = 0; y < height; ++y) { var alphaScanline = (byte *)alphaSrc.GetScanlinePointer(y).ToPointer(); var redScanline = (byte *)redSrc.GetScanlinePointer(y).ToPointer(); var greenScanline = (byte *)greenSrc.GetScanlinePointer(y).ToPointer(); var blueScanline = (byte *)blueSrc.GetScanlinePointer(y).ToPointer(); var combinedScanline = (byte *)combined.GetScanlinePointer(y).ToPointer(); for (int x = 0; x < width; ++x) { combinedScanline[FreeImage.FI_RGBA_BLUE] = blueScanline[blueChannel]; combinedScanline[FreeImage.FI_RGBA_GREEN] = greenScanline[greenChannel]; combinedScanline[FreeImage.FI_RGBA_RED] = redScanline[redChannel]; combinedScanline[FreeImage.FI_RGBA_ALPHA] = alphaScanline[alphaChannel]; alphaScanline += alphaWalk; redScanline += redWalk; greenScanline += greenWalk; blueScanline += blueWalk; combinedScanline += combinedWalk; } } return(combined); }
/// <summary> /// Create a pixel box for this FreeImageBitmap, note that ogre will populate the pixel box upside down, so you will need to flip the image /// afterward. Also you must Dispose the PixelBox returned by this function. /// </summary> /// /// <param name="bitmap">This object.</param> /// <param name="format">The format of the pixel box.</param> /// <returns>A PixelBox with the given format for the FreeImageBitmap.</returns> unsafe public static PixelBox createPixelBox(this FreeImageBitmap bitmap, OgrePlugin.PixelFormat format) { return(new PixelBox(0, 0, bitmap.Width, bitmap.Height, format, bitmap.GetScanlinePointer(0).ToPointer())); }
/// <summary> /// Compile input images into WAD texture file. /// </summary> /// <param name="outputFilename">Output wad file path.</param> /// <param name="images">Input image files.</param> /// <param name="names">Names of textures.</param> /// <param name="reserverLastPalColor">Reserve last color in palette if name starts with {.</param> public static void CreateWad(string outputFilename, string[] images, string[] names, Color alphaReplacementColor, bool reserverLastPalColor = false) { using (FileStream fs = new FileStream(outputFilename, FileMode.Create)) using (BinaryWriter bw = new BinaryWriter(fs)) { //Convert bitmaps to 8bpp format List <FreeImageBitmap> imgs = new List <FreeImageBitmap>(); for (int i = 0; i < images.Length; i++) { //Quantize images FreeImageBitmap originalImage = new FreeImageBitmap(images[i]); //If texture will be transparent, reserve last color if enabled bool reserveLastClr = (names[i].StartsWith("{") && reserverLastPalColor); bool isTransparentImage = originalImage.IsTransparent; bool is8Bpp = originalImage.BitsPerPixel == 8; int r = reserveLastClr ? 1 : 0; if (isTransparentImage) { originalImage.SwapColors(new RGBQUAD(Color.Transparent), new RGBQUAD(alphaReplacementColor), false); } originalImage.Quantize(FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, MaxPaletteColors - r); originalImage.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP); if (reserveLastClr) { if (isTransparentImage) { bool foundReplacementColor = false; for (int pindex = 0; pindex < originalImage.Palette.Length; pindex++) { RGBQUAD rgb = originalImage.Palette.GetValue(pindex); if (rgb.rgbRed == alphaReplacementColor.R && rgb.rgbGreen == alphaReplacementColor.G && rgb.rgbBlue == alphaReplacementColor.B) { var lastColor = originalImage.Palette.GetValue(MaxPaletteColors - 1); originalImage.Palette[pindex] = lastColor; originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor); originalImage.SwapPaletteIndices((byte)pindex, MaxPaletteColors - 1); foundReplacementColor = true; break; } } // If didn't found replacement, set directly last alpha color if (!foundReplacementColor) { originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor); } } else { originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor); } } imgs.Add(originalImage); } uint[] offsets = new uint[images.Length]; uint[] sizes = new uint[images.Length]; //WAD header bw.Write(WadHeaderId); bw.Write(images.Length); bw.Write(0); //This will be changed later //Write textures for (int i = 0; i < images.Length; i++) { uint posTextureStart = (uint)bw.BaseStream.Position; offsets[i] = posTextureStart; //Texture name byte[] name = CreateTextureName(names[i]); bw.Write(name, 0, name.Length); //Texture dimensions bw.Write(imgs[i].Width); bw.Write(imgs[i].Height); //Offsets uint posImage = (uint)(bw.BaseStream.Position - posTextureStart); bw.Write(posImage + 16); //image int pixelSize = ((imgs[i].Width) * (imgs[i].Height)); int m1 = ((imgs[i].Width / 2) * (imgs[i].Height / 2)); int m2 = ((imgs[i].Width / 4) * (imgs[i].Height / 4)); int m3 = ((imgs[i].Width / 8) * (imgs[i].Height / 8)); bw.Write((uint)(posImage + pixelSize + 16)); //mipmap1 bw.Write((uint)(posImage + pixelSize + m1 + 16)); //mipmap2 bw.Write((uint)(posImage + pixelSize + m1 + m2 + 16)); //mipmap3 //Write pixel data imgs[i].RotateFlip(RotateFlipType.RotateNoneFlipX); byte[] arr = new byte[imgs[i].Width * imgs[i].Height]; System.Runtime.InteropServices.Marshal.Copy(imgs[i].GetScanlinePointer(0), arr, 0, arr.Length); Array.Reverse(arr); bw.Write(arr); // //Mip map data int factor = 2; for (int a = 0; a < 3; a++) { int widthMM = (imgs[i].Width / factor); int heightMM = (imgs[i].Height / factor); using (FreeImageBitmap clBmp = new FreeImageBitmap(imgs[i])) { //TODO: Transparent png clBmp.Rescale(widthMM, heightMM, FREE_IMAGE_FILTER.FILTER_LANCZOS3); clBmp.Quantize(FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, MaxPaletteColors, imgs[i].Palette); byte[] arrMM = new byte[widthMM * heightMM]; System.Runtime.InteropServices.Marshal.Copy(clBmp.GetScanlinePointer(0), arrMM, 0, arrMM.Length); Array.Reverse(arrMM); bw.Write(arrMM); } factor *= 2; } //Unknown 2 bytes bw.Write(new byte[] { 0x00, 0x01 }); //Write color palette for (int p = 0; p < imgs[i].Palette.Length; p++) { bw.Write(imgs[i].Palette[p].rgbRed); bw.Write(imgs[i].Palette[p].rgbGreen); bw.Write(imgs[i].Palette[p].rgbBlue); } //Padding bw.Write(new byte[] { 0x00, 0x00 }); sizes[i] = (uint)bw.BaseStream.Position - posTextureStart; } long posLumps = bw.BaseStream.Position; bw.Seek(8, SeekOrigin.Begin); bw.Write((uint)posLumps); bw.Seek((int)posLumps, SeekOrigin.Begin); //Write Lumps infos for (int i = 0; i < images.Length; i++) { bw.Write(offsets[i]); bw.Write(sizes[i]); bw.Write(sizes[i]); bw.Write((byte)0x43); bw.Write((byte)0); bw.Write(new byte[] { 0x00, 0x00 }); byte[] name = CreateTextureName(names[i]); bw.Write(name, 0, name.Length); } //Free resources for (int i = 0; i < imgs.Count; i++) { imgs[i].Dispose(); } } }
public unsafe void RotateFlip() { FreeImageBitmap fib = new FreeImageBitmap(2, 2, PixelFormat.Format32bppArgb); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.RotateNoneFlipX); Assert.AreEqual(0x00000002, ((int *)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000001, ((int *)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000004, ((int *)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000003, ((int *)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.RotateNoneFlipY); Assert.AreEqual(0x00000003, ((int *)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000004, ((int *)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000001, ((int *)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000002, ((int *)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.RotateNoneFlipXY); Assert.AreEqual(0x00000004, ((int *)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000003, ((int *)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000002, ((int *)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000001, ((int *)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.Rotate90FlipNone); Assert.AreEqual(0x00000003, ((int *)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000001, ((int *)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000004, ((int *)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000002, ((int *)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.Rotate90FlipX); Assert.AreEqual(0x00000001, ((int *)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000003, ((int *)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000002, ((int *)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000004, ((int *)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.Rotate90FlipY); Assert.AreEqual(0x00000004, ((int *)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000002, ((int *)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000003, ((int *)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000001, ((int *)fib.GetScanlinePointer(1))[1]); fib.Dispose(); }
/// <summary> /// Add an image to this page, will return true if the image was sucessfully added to the page. /// </summary> /// <param name="name"></param> /// <param name="image"></param> /// <returns></returns> internal unsafe bool addImage(String name, FreeImageBitmap image) { ImagePackTreeNode node = rootNode.insert(name, image); if (node != null) { using (PixelBox pixelBox = new PixelBox(0, 0, image.Width, image.Height, OgreDrawingUtility.getOgreFormat(image.PixelFormat), image.GetScanlinePointer(0).ToPointer())) { Rectangle locationRect = node.LocationRect; bufferPtr.Value.blitFromMemory(pixelBox, new IntRect(locationRect.Left, locationRect.Top, locationRect.Right, locationRect.Bottom)); imageInfo.Add(name, node); } return(true); } else { return(false); } }
private unsafe void ResetRotateBitmap(FreeImageBitmap fib) { ((int*)fib.GetScanlinePointer(0))[0] = 0x00000001; ((int*)fib.GetScanlinePointer(0))[1] = 0x00000002; ((int*)fib.GetScanlinePointer(1))[0] = 0x00000003; ((int*)fib.GetScanlinePointer(1))[1] = 0x00000004; }
public unsafe void RotateFlip() { FreeImageBitmap fib = new FreeImageBitmap(2, 2, PixelFormat.Format32bppArgb); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.RotateNoneFlipX); Assert.AreEqual(0x00000002, ((int*)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000001, ((int*)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000004, ((int*)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000003, ((int*)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.RotateNoneFlipY); Assert.AreEqual(0x00000003, ((int*)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000004, ((int*)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000001, ((int*)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000002, ((int*)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.RotateNoneFlipXY); Assert.AreEqual(0x00000004, ((int*)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000003, ((int*)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000002, ((int*)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000001, ((int*)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.Rotate90FlipNone); Assert.AreEqual(0x00000003, ((int*)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000001, ((int*)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000004, ((int*)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000002, ((int*)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.Rotate90FlipX); Assert.AreEqual(0x00000001, ((int*)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000003, ((int*)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000002, ((int*)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000004, ((int*)fib.GetScanlinePointer(1))[1]); ResetRotateBitmap(fib); fib.RotateFlip(RotateFlipType.Rotate90FlipY); Assert.AreEqual(0x00000004, ((int*)fib.GetScanlinePointer(0))[0]); Assert.AreEqual(0x00000002, ((int*)fib.GetScanlinePointer(0))[1]); Assert.AreEqual(0x00000003, ((int*)fib.GetScanlinePointer(1))[0]); Assert.AreEqual(0x00000001, ((int*)fib.GetScanlinePointer(1))[1]); fib.Dispose(); }
public unsafe void GetRotatedInstance() { using (FreeImageBitmap fib = new FreeImageBitmap(2, 2, PixelFormat.Format32bppArgb)) { ((int*)fib.GetScanlinePointer(0))[0] = 0x1; ((int*)fib.GetScanlinePointer(0))[1] = 0x2; ((int*)fib.GetScanlinePointer(1))[0] = 0x3; ((int*)fib.GetScanlinePointer(1))[1] = 0x4; using (FreeImageBitmap conv = fib.GetRotatedInstance(90d)) { Assert.IsNotNull(conv); Assert.AreEqual(((int*)conv.GetScanlinePointer(0))[0], 0x3); Assert.AreEqual(((int*)conv.GetScanlinePointer(0))[1], 0x1); Assert.AreEqual(((int*)conv.GetScanlinePointer(1))[0], 0x4); Assert.AreEqual(((int*)conv.GetScanlinePointer(1))[1], 0x2); } } }