private void breakUpImage(FreeImageBitmap image) { if (imageNeedsBreakup) { imageNeedsBreakup = false; foreach (var tile in tiles) { var tileImage = new FreeImageBitmap( (int)(image.Width * tile.Width), (int)(image.Height * tile.Height), FreeImageAPI.PixelFormat.Format32bppArgb); using (var destBox = tileImage.createPixelBox(PixelFormat.PF_A8R8G8B8)) { using (var sourceBox = image.createPixelBox()) { sourceBox.Left = (uint)(image.Width * tile.NodeLeft); sourceBox.Top = (uint)(image.Height * tile.NodeTop); sourceBox.Right = (uint)(sourceBox.Left + tileImage.Width); sourceBox.Bottom = (uint)(sourceBox.Top + tileImage.Height); PixelBox.BulkPixelConversion(sourceBox, destBox); } } //tileImage.saveToFile($"tilesdebug/{tile.NodeLeft}_{tile.NodeTop}.bmp", FREE_IMAGE_FORMAT.FIF_BMP); tile.Image = tileImage; } } }
//int imageId = 0; public void rescaleImage(FreeImageBitmap image, Size size, FREE_IMAGE_FILTER filter) { breakUpImage(image); //float wPercent = size.Width / (float)firstSeenImageSize.Width; //float hPercent = size.Height / (float)firstSeenImageSize.Height; //var newTileSize = new Size((int)(wPercent * originalTileSize.Width), (int)(hPercent * originalTileSize.Height)); image.Rescale(size, filter); //Need to resize the image, but will replace with individually sized tiles //image.saveToFile(imageId + "orig.bmp", FREE_IMAGE_FORMAT.FIF_BMP); using (var destBox = image.createPixelBox()) { foreach (var tile in tiles) { var newTileSize = new Size((int)(size.Width * tile.Width), (int)(size.Height * tile.Height)); tile.Image.Rescale(newTileSize, filter); using (var srcBox = tile.Image.createPixelBox(PixelFormat.PF_A8R8G8B8)) { var tx = size.Width * tile.NodeLeft; var ty = size.Height * tile.NodeTop; destBox.Left = (uint)tx; destBox.Top = (uint)ty; destBox.Right = (uint)(tx + newTileSize.Width); destBox.Bottom = (uint)(ty + newTileSize.Height); PixelBox.BulkPixelConversion(srcBox, destBox); //image.saveToFile("show/" + imageId++ + "tiled.bmp", FREE_IMAGE_FORMAT.FIF_BMP); } } } //image.saveToFile(imageId++ + "tiled.bmp", FREE_IMAGE_FORMAT.FIF_BMP); }
/// <summary> /// Copy the given RenderTarget with the specified format. /// </summary> /// <param name="bitmap"></param> /// <param name="renderTarget"></param> /// <param name="format"></param> public static void copyFromRenderTarget(this FreeImageBitmap bitmap, RenderTarget renderTarget, OgrePlugin.PixelFormat format) { using (PixelBox pixelBox = bitmap.createPixelBox(format)) { renderTarget.copyContentsToMemory(pixelBox, RenderTarget.FrameBuffer.FB_AUTO); } bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); }
public FeedbackBuffer(VirtualTextureManager virtualTextureManager, IntSize2 renderSize, int id, uint visibilityMask) { this.id = id; this.virtualTextureManager = virtualTextureManager; this.visibilityMask = visibilityMask; texture = TextureManager.getInstance().createManual(TextureName, VirtualTextureManager.ResourceGroup, TextureType.TEX_TYPE_2D, (uint)renderSize.Width, (uint)renderSize.Height, 1, 0, OgrePlugin.PixelFormat.PF_A8R8G8B8, TextureUsage.TU_RENDERTARGET, null, false, 0); fullBitmap = new FreeImageBitmap((int)texture.Value.Width, (int)texture.Value.Height, FreeImageAPI.PixelFormat.Format32bppRgb); fullBitmapBox = fullBitmap.createPixelBox(OgrePlugin.PixelFormat.PF_A8R8G8B8); pixelBuffer = texture.Value.getBuffer(); pixelBuffer.Value.OptimizeReadback = true; renderTexture = pixelBuffer.Value.getRenderTarget(); renderTexture.setAutoUpdated(false); }
/// <summary> /// Works ok but not all tiles repeat like this. /// </summary> private static void padRepeatOtherSide(FreeImageBitmap image, int padding, int pageSize, IntSize2 fullPageSize, IntRect imageRect, PixelBox pageBox) { //Pad by repeating //Top using (PixelBox altSrcBox = image.createPixelBox()) { pageBox.Top = 0; pageBox.Bottom = (uint)padding; pageBox.Left = (uint)padding; pageBox.Right = (uint)(fullPageSize.Width - padding); altSrcBox.Top = (uint)(imageRect.Bottom - padding); altSrcBox.Bottom = (uint)imageRect.Bottom; altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + pageSize); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } //Bottom using (PixelBox altSrcBox = image.createPixelBox()) { pageBox.Top = (uint)(fullPageSize.Height - padding); pageBox.Bottom = (uint)fullPageSize.Height; pageBox.Left = (uint)padding; pageBox.Right = (uint)(fullPageSize.Width - padding); altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + padding); altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + pageSize); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } //Left using (PixelBox altSrcBox = image.createPixelBox()) { pageBox.Top = (uint)padding; pageBox.Bottom = (uint)(fullPageSize.Height - padding); pageBox.Left = 0; pageBox.Right = (uint)padding; altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + pageSize); altSrcBox.Left = (uint)(imageRect.Right - padding); altSrcBox.Right = (uint)imageRect.Right; PixelBox.BulkPixelConversion(altSrcBox, pageBox); } //Right using (PixelBox altSrcBox = image.createPixelBox()) { pageBox.Top = (uint)padding; pageBox.Bottom = (uint)(fullPageSize.Height - padding); pageBox.Left = (uint)(fullPageSize.Width - padding); pageBox.Right = (uint)fullPageSize.Width; altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + pageSize); altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + padding); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } }
/// <summary> /// This one seems to work the best, but falls apart at lower mip levels on the virtual texture. /// </summary> private static void padFillColor(FreeImageBitmap image, int padding, int pageSize, IntSize2 fullPageSize, IntRect imageRect, PixelBox pageBox) { //Pad by repeating //Top using (PixelBox altSrcBox = image.createPixelBox()) { altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + 1); altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + pageSize); for (int i = 0; i < padding; ++i) { pageBox.Top = (uint)i; pageBox.Bottom = (uint)(i + 1); pageBox.Left = (uint)padding; pageBox.Right = (uint)(fullPageSize.Width - padding); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } } //Bottom using (PixelBox altSrcBox = image.createPixelBox()) { altSrcBox.Top = (uint)(imageRect.Bottom - 1); altSrcBox.Bottom = (uint)imageRect.Bottom; altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + pageSize); for (int i = 0; i < padding; ++i) { pageBox.Top = (uint)(fullPageSize.Height - i - 1); pageBox.Bottom = (uint)pageBox.Top + 1; pageBox.Left = (uint)padding; pageBox.Right = (uint)(fullPageSize.Width - padding); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } } //Left using (PixelBox altSrcBox = image.createPixelBox()) { altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + pageSize); altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + 1); for (int i = 0; i < padding; ++i) { pageBox.Top = (uint)padding; pageBox.Bottom = (uint)(fullPageSize.Height - padding); pageBox.Left = (uint)i; pageBox.Right = (uint)i + 1; PixelBox.BulkPixelConversion(altSrcBox, pageBox); } } //Right using (PixelBox altSrcBox = image.createPixelBox()) { altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + pageSize); altSrcBox.Left = (uint)(imageRect.Right - 1); altSrcBox.Right = (uint)imageRect.Right; for (int i = 0; i < padding; ++i) { pageBox.Top = (uint)padding; pageBox.Bottom = (uint)(fullPageSize.Height - padding); pageBox.Left = (uint)(fullPageSize.Width - i - 1); pageBox.Right = (uint)(pageBox.Left + 1); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } } }
public void extractPage(FreeImageBitmap image, int padding, Stream stream, PagedImage pagedImage, int pageSize, IntSize2 fullPageSize, int size, FREE_IMAGE_FORMAT outputFormat, FREE_IMAGE_SAVE_FLAGS saveFlags) { IntRect serialImageRect = new IntRect(); MemoryStream[] memoryStreams = new MemoryStream[size]; FreeImageBitmap[] pages = new FreeImageBitmap[size]; try { for (int i = 0; i < size; ++i) { memoryStreams[i] = new MemoryStream(); pages[i] = new FreeImageBitmap(fullPageSize.Width, fullPageSize.Height, FreeImageAPI.PixelFormat.Format32bppArgb); } //Calculate pages as tiles, always repeat outer limits for (int y = 0; y < size; ++y) { serialImageRect.Height = pageSize; serialImageRect.Top = y * pageSize; Parallel.For(0, size, x => //for (int x = 0; x < size; ++x) { IntRect imageRect = serialImageRect; imageRect.Width = pageSize; imageRect.Left = x * pageSize; using (var pageBox = pages[x].createPixelBox(PixelFormat.PF_A8R8G8B8)) { pageBox.Top += (uint)padding; pageBox.Bottom -= (uint)padding; pageBox.Left += (uint)padding; pageBox.Right -= (uint)padding; using (var imageBox = image.createPixelBox()) { imageBox.Left = (uint)imageRect.Left; imageBox.Right = (uint)imageRect.Right; imageBox.Top = (uint)imageRect.Top; imageBox.Bottom = (uint)imageRect.Bottom; PixelBox.BulkPixelConversion(imageBox, pageBox); } padFillColor(image, padding, pageSize, fullPageSize, imageRect, pageBox); } //int startPos = (int)stream.Position; pages[x].RotateFlip(RotateFlipType.RotateNoneFlipY); //Have to flip the page over for ogre to be happy pages[x].Save(memoryStreams[x], outputFormat, saveFlags); //pages[x].saveToFile($"page/page{image.Width}_x{x}y_{y}.bmp", FREE_IMAGE_FORMAT.FIF_BMP); memoryStreams[x].Position = 0; //++pagedImage.numImages; //pagedImage.pages.Add(new ImageInfo(startPos, (int)(stream.Position))); }); //} for (int x = 0; x < size; ++x) { int startPos = (int)stream.Position; //page.RotateFlip(RotateFlipType.RotateNoneFlipY); //Have to flip the page over for ogre to be happy //page.Save(stream, outputFormat, saveFlags); memoryStreams[x].CopyTo(stream); ++pagedImage.NumImages; pagedImage.Pages.Add(new PagedImage.ImageInfo(startPos, (int)(stream.Position))); memoryStreams[x].Dispose(); memoryStreams[x] = new MemoryStream(); } } } finally { for (int i = 0; i < size; ++i) { memoryStreams[i].Dispose(); pages[i].Dispose(); } } }
public void extractPage(FreeImageBitmap image, int padding, Stream stream, PagedImage pagedImage, int pageSize, IntSize2 fullPageSize, int size, FREE_IMAGE_FORMAT outputFormat, FREE_IMAGE_SAVE_FLAGS saveFlags) { bool topSide, bottomSide; IntRect serialImageRect = new IntRect(); MemoryStream[] memoryStreams = new MemoryStream[size]; FreeImageBitmap[] pages = new FreeImageBitmap[size]; try { for (int i = 0; i < size; ++i) { memoryStreams[i] = new MemoryStream(); pages[i] = new FreeImageBitmap(fullPageSize.Width, fullPageSize.Height, FreeImageAPI.PixelFormat.Format32bppArgb); } //Calculate pages, note that there is overlap by padding between them this is intentional for (int y = 0; y < size; ++y) { serialImageRect.Height = fullPageSize.Height; serialImageRect.Top = y * pageSize - padding; topSide = serialImageRect.Top < 0; if (topSide) { serialImageRect.Top = 0; serialImageRect.Height -= padding; } bottomSide = serialImageRect.Bottom > image.Height; if (bottomSide) { if (topSide) { //Take entire image serialImageRect.Top = 0; serialImageRect.Height = image.Height; } else { //Extra row on top, bottom flush with texture bottom will add extra pixel row on bottom will add extra pixel row on bottom below serialImageRect.Top = image.Height - pageSize - padding; serialImageRect.Height -= padding; } } Parallel.For(0, size, x => //for (int x = 0; x < size; ++x) { bool leftSide, rightSide; IntRect imageRect = serialImageRect; imageRect.Width = fullPageSize.Width; imageRect.Left = x * pageSize - padding; leftSide = imageRect.Left < 0; if (leftSide) { imageRect.Left = 0; imageRect.Width -= padding; } rightSide = imageRect.Right > image.Width; if (rightSide) { if (leftSide) { //Take entire image imageRect.Left = 0; imageRect.Width = image.Width; } else { //Extra row on left, right flush with texture right will add extra pixel row on right below imageRect.Left = image.Width - pageSize - padding; imageRect.Width -= padding; } } using (var pageBox = pages[x].createPixelBox(PixelFormat.PF_A8R8G8B8)) { if (topSide) { pageBox.Top += (uint)padding; } if (bottomSide) { pageBox.Bottom -= (uint)padding; } if (leftSide) { pageBox.Left += (uint)padding; } if (rightSide) { pageBox.Right -= (uint)padding; } using (var imageBox = image.createPixelBox()) { imageBox.Left = (uint)imageRect.Left; imageBox.Right = (uint)imageRect.Right; imageBox.Top = (uint)imageRect.Top; imageBox.Bottom = (uint)imageRect.Bottom; PixelBox.BulkPixelConversion(imageBox, pageBox); } if (topSide) { using (PixelBox altSrcBox = image.createPixelBox()) { pageBox.Top = 0; pageBox.Bottom = (uint)padding; pageBox.Left = (uint)padding; pageBox.Right = (uint)(fullPageSize.Width - padding); altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + padding); altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + pageSize); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } } if (bottomSide) { using (PixelBox altSrcBox = image.createPixelBox()) { pageBox.Top = (uint)(fullPageSize.Height - padding); pageBox.Bottom = (uint)fullPageSize.Height; pageBox.Left = (uint)padding; pageBox.Right = (uint)(fullPageSize.Width - padding); altSrcBox.Top = (uint)(imageRect.Bottom - padding); altSrcBox.Bottom = (uint)imageRect.Bottom; altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + pageSize); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } } if (leftSide) { using (PixelBox altSrcBox = image.createPixelBox()) { pageBox.Top = (uint)padding; pageBox.Bottom = (uint)(fullPageSize.Height - padding); pageBox.Left = 0; pageBox.Right = (uint)padding; altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + pageSize); altSrcBox.Left = (uint)imageRect.Left; altSrcBox.Right = (uint)(imageRect.Left + padding); PixelBox.BulkPixelConversion(altSrcBox, pageBox); } } if (rightSide) { using (PixelBox altSrcBox = image.createPixelBox()) { pageBox.Top = (uint)padding; pageBox.Bottom = (uint)(fullPageSize.Height - padding); pageBox.Left = (uint)(fullPageSize.Width - padding); pageBox.Right = (uint)fullPageSize.Width; altSrcBox.Top = (uint)imageRect.Top; altSrcBox.Bottom = (uint)(imageRect.Top + pageSize); altSrcBox.Left = (uint)(imageRect.Right - padding); altSrcBox.Right = (uint)imageRect.Right; PixelBox.BulkPixelConversion(altSrcBox, pageBox); } } } //int startPos = (int)stream.Position; pages[x].RotateFlip(RotateFlipType.RotateNoneFlipY); //Have to flip the page over for ogre to be happy pages[x].Save(memoryStreams[x], outputFormat, saveFlags); memoryStreams[x].Position = 0; //++pagedImage.numImages; //pagedImage.pages.Add(new ImageInfo(startPos, (int)(stream.Position))); }); //} for (int x = 0; x < size; ++x) { int startPos = (int)stream.Position; //page.RotateFlip(RotateFlipType.RotateNoneFlipY); //Have to flip the page over for ogre to be happy //page.Save(stream, outputFormat, saveFlags); memoryStreams[x].CopyTo(stream); ++pagedImage.NumImages; pagedImage.Pages.Add(new PagedImage.ImageInfo(startPos, (int)(stream.Position))); memoryStreams[x].Dispose(); memoryStreams[x] = new MemoryStream(); } } } finally { for (int i = 0; i < size; ++i) { memoryStreams[i].Dispose(); pages[i].Dispose(); } } }