//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); }
public void FreeImageResize() { using (var image = new FreeImageBitmap(Width, Height)) { image.Rescale(ResizedWidth, ResizedHeight, FREE_IMAGE_FILTER.FILTER_BICUBIC); } }
public void makeSampleImage(FreeImageBitmap bitmap) { if (LoadLogo != null) { using (FreeImageBitmap logo = LoadLogo()) { float sizeRatio = (float)bitmap.Width / logo.Width; int finalLogoWidth = (int)(logo.Width * sizeRatio); int finalLogoHeight = (int)(logo.Height * sizeRatio); int currentY = 0; int imageHeight = bitmap.Height; bitmap.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP); logo.Rescale(finalLogoWidth, finalLogoHeight, FREE_IMAGE_FILTER.FILTER_BILINEAR); while (currentY < imageHeight) { int sectionHeight = logo.Height; if (currentY + sectionHeight > imageHeight) { sectionHeight = imageHeight - currentY; } using (FreeImageBitmap section = bitmap.Copy(0, currentY, logo.Width, currentY + sectionHeight)) { using (FreeImageBitmap logoComposite = logo.Copy(0, 0, logo.Width, sectionHeight)) { logoComposite.Composite(false, null, section); bitmap.Paste(logoComposite, 0, currentY, int.MaxValue); currentY += finalLogoHeight; } } } } } }
public static void Main(string[] args) { var icoFile = args[1]; var fiBitmap = new FreeImageBitmap(args[0]); var first = true; foreach (var size in Sizes) { if (fiBitmap.Width < size || fiBitmap.Height < size) { continue; } fiBitmap.Rescale(size, size, FREE_IMAGE_FILTER.FILTER_BICUBIC); if (first) { first = false; fiBitmap.Save(icoFile); } else { fiBitmap.SaveAdd(icoFile); } } }
public void Resize(int width) { FreeImageBitmap bmp = new FreeImageBitmap(ImageFromData(Data)); int ratio = (int)((double)bmp.Height / bmp.Width * width); bmp.Rescale(width, ratio, FREE_IMAGE_FILTER.FILTER_BOX); Data = ImageToByte((Image)(bmp.Clone() as FreeImageBitmap)); bmp.Dispose(); }
/// <summary> /// Return an image from a given filename /// </summary> /// <param name = "fileName"></param> /// <param name = "size"></param> /// <returns></returns> private Image GetImageFromFile(string fileName, out Size size) { FreeImageBitmap img = null; size = new Size(0, 0); try { img = new FreeImageBitmap(fileName); size = img.Size; // convert Image Size to 64 x 64 for display in the Imagelist img.Rescale(64, 64, FREE_IMAGE_FILTER.FILTER_BOX); } catch (Exception ex) { log.Error("File has invalid Picture: {0} {1}", fileName, ex.Message); } return(img != null ? (Image)img : null); }
private FreeImageBitmap simpleRender(int width, int height, int aaMode, bool transparentBG, Engine.Color bgColor, RenderTexture renderTexture) { renderTexture.getViewport(0).clear(FrameBufferType.FBT_COLOUR | FrameBufferType.FBT_DEPTH | FrameBufferType.FBT_STENCIL, bgColor); renderTexture.update(); OgrePlugin.PixelFormat format = OgrePlugin.PixelFormat.PF_A8R8G8B8; FreeImageAPI.PixelFormat bitmapFormat = FreeImageAPI.PixelFormat.Format32bppRgb; if (transparentBG) { bitmapFormat = FreeImageAPI.PixelFormat.Format32bppArgb; } FreeImageBitmap bitmap = new FreeImageBitmap(width, height, bitmapFormat); bitmap.copyFromRenderTarget(renderTexture, format); //Resize if aa is active if (aaMode > 1) { int smallWidth = width / aaMode; int smallHeight = height / aaMode; bitmap.Rescale(smallWidth, smallHeight, FREE_IMAGE_FILTER.FILTER_BILINEAR); } return(bitmap); }
public void Resize(int width) { FreeImageBitmap bmp = new FreeImageBitmap(Data); int ratio = (int)((double)bmp.Height / bmp.Width * width); bmp.Rescale(width, ratio, FREE_IMAGE_FILTER.FILTER_BOX); Data = (Image) (bmp.Clone() as FreeImageBitmap); bmp.Dispose(); }
/// <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(); } } }
// Replaces the current bitmap with the given one. private void ReplaceBitmap(FreeImageBitmap newBitmap) { // Checks whether the bitmap is usable if (newBitmap == null || newBitmap.IsDisposed) { MessageBox.Show( "Nispodziewany błąd.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } // Check whether the image type of the new bitmap is 'FIT_BITMAP'. // If not convert to 'FIT_BITMAP'. if (newBitmap.ImageType != FREE_IMAGE_TYPE.FIT_BITMAP) { if (!newBitmap.ConvertType(FREE_IMAGE_TYPE.FIT_BITMAP, true)) { MessageBox.Show( "Błąd konwersji bitmapy do standardowego typu.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } // Dispose the old bitmap only in case it exists and // the old instance is another than the new one. if ((bitmap != null) && !object.ReferenceEquals(bitmap, newBitmap)) { bitmap.Dispose(); } if ((smallbitmap != null) && !object.ReferenceEquals(smallbitmap, bitmap)) { smallbitmap.Dispose(); } bitmap = newBitmap; smallbitmap = bitmap; smallbitmap.Rescale(mForm.smallbitmap.Width, mForm.smallbitmap.Height, FREE_IMAGE_FILTER.FILTER_BICUBIC); UpdateBitmapInformations(); }
public static Response GetPageImage(Guid id, int page, int width, int height, IResponseFormatter response) { // Restrict access to the FreeImage library to one thread at a time. lock (lockThis) { int max_width = 0; int max_height = 0; bool thumbnail = !(width == -1 && height == -1); bool processed = false; string filename = string.Format("{0}-p{1}-w{2}-h{3}.jpg", id, page, width, height); if (thumbnail) { MemoryStream cachestream = ImageCache.Instance.LoadFromCache(filename, true); // Cached thumbnails are assumed to be in the correct format and adhere to the size/format restrictions of the ipad. if (cachestream != null) { return(response.FromStream(cachestream, MimeTypes.GetMimeType(".jpg"))); } } else { // Check if a processed (rescaled and/or progressive) image is cached. string processed_filename = string.Format("{0}-p{1}-processed.jpg", id, page); MemoryStream cachestream = ImageCache.Instance.LoadFromCache(processed_filename, false); if (cachestream != null) { return(response.FromStream(cachestream, MimeTypes.GetMimeType(".jpg"))); } } MemoryStream stream = null; // Check if original image is in the cache. string org_filename = string.Format("{0}-p{1}.jpg", id, page); stream = ImageCache.Instance.LoadFromCache(org_filename, false); if (stream == null) { // Image is not in the cache, get it via ComicRack. var bytes = GetPageImageBytes(id, page); if (bytes == null) { return(HttpStatusCode.NotFound); } stream = new MemoryStream(bytes); // Always save the original page to the cache ImageCache.Instance.SaveToCache(org_filename, stream, false); } stream.Seek(0, SeekOrigin.Begin); #if USE_GDI Bitmap bitmap = new Bitmap(stream, false); int bitmap_width = (int)bitmap.Width; int bitmap_height = (int)bitmap.Height; #elif USE_DIB FIBITMAP dib = FreeImage.LoadFromStream(stream); if (dib == null) { Console.WriteLine("Loading bitmap failed. Aborting."); // Check whether there was an error message. return(HttpStatusCode.InternalServerError); } int bitmap_width = (int)FreeImage.GetWidth(dib); int bitmap_height = (int)FreeImage.GetHeight(dib); #elif USE_FIB FreeImageBitmap fib = FreeImageBitmap.FromStream(stream, false); if (fib == null) { Console.WriteLine("Loading bitmap failed. Aborting."); // Check whether there was an error message. return(HttpStatusCode.InternalServerError); } int bitmap_width = (int)fib.Width; int bitmap_height = (int)fib.Height; #endif if (ImageCache.Instance.use_max_dimension) { int mw, mh; if (bitmap_width >= bitmap_height) { mw = ImageCache.Instance.max_dimension_long; mh = ImageCache.Instance.max_dimension_short; } else { mw = ImageCache.Instance.max_dimension_short; mh = ImageCache.Instance.max_dimension_long; } if (bitmap_width > mw || bitmap_height > mh) { double scaleW = (double)mw / (double)bitmap_width; double scaleH = (double)mh / (double)bitmap_height; double scale = Math.Min(scaleW, scaleH); max_width = (int)Math.Floor(scale * bitmap_width); max_height = (int)Math.Floor(scale * bitmap_height); } else { max_width = bitmap_width; max_height = bitmap_height; } } else // Check if the image dimensions exceeds the maximum image dimensions if ((bitmap_width * bitmap_height) > ImageCache.Instance.maximum_imagesize) { max_width = (int)Math.Floor(Math.Sqrt((double)bitmap_width / (double)bitmap_height * (double)ImageCache.Instance.maximum_imagesize)); max_height = (int)Math.Floor((double)max_width * (double)bitmap_height / (double)bitmap_width); } else { max_width = bitmap_width; max_height = bitmap_height; } // Calculate the dimensions of the returned image. int result_width = width; int result_height = height; if (result_width == -1 && result_height == -1) { result_width = max_width; result_height = max_height; } else { if (result_width == -1) { result_height = Math.Min(max_height, result_height); double ratio = (double)result_height / (double)max_height; result_width = (int)Math.Floor(((double)max_width * ratio)); } else if (result_height == -1) { result_width = Math.Min(max_width, result_width); double ratio = (double)result_width / (double)max_width; result_height = (int)Math.Floor(((double)max_height * ratio)); } } // TODO: do this per requesting target device instead of using one global setting. // Resize ? if (result_width != bitmap_width || result_height != bitmap_height) { processed = true; #if USE_DIB || USE_FIB //FREE_IMAGE_FILTER resizer = FREE_IMAGE_FILTER.FILTER_BICUBIC; FREE_IMAGE_FILTER resizer = FREE_IMAGE_FILTER.FILTER_LANCZOS3; #if USE_FIB fib.Rescale(result_width, result_height, resizer); #else FIBITMAP newdib = FreeImage.Rescale(dib, result_width, result_height, resizer); if (!newdib.IsNull) { FreeImage.Unload(dib); dib.SetNull(); dib = newdib; } #endif #elif USE_GDI Bitmap resizedBitmap = Resize(bitmap, result_width, result_height); bitmap.Dispose(); bitmap = resizedBitmap; resizedBitmap = null; #endif } // Check if the image must be converted to progressive jpeg if (ImageCache.Instance.use_progressive_jpeg && (result_width * result_height) >= ImageCache.Instance.progressive_jpeg_size_threshold) { processed = true; // Convert image to progressive jpeg // FreeImage source code reveals that lower 7 bits of the FREE_IMAGE_SAVE_FLAGS enum are used for low-level quality control. FREE_IMAGE_SAVE_FLAGS quality = (FREE_IMAGE_SAVE_FLAGS)ImageCache.Instance.progressive_jpeg_quality; FREE_IMAGE_SAVE_FLAGS flags = FREE_IMAGE_SAVE_FLAGS.JPEG_SUBSAMPLING_444 | FREE_IMAGE_SAVE_FLAGS.JPEG_PROGRESSIVE | quality; #if USE_DIB || USE_FIB stream.Dispose(); stream = new MemoryStream(); #if USE_FIB fib.Save(stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags); fib.Dispose(); #else FreeImage.SaveToStream(dib, stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags); FreeImage.Unload(dib); dib.SetNull(); #endif #else FIBITMAP dib = FreeImage.CreateFromBitmap(bitmap); bitmap.Dispose(); bitmap = null; stream.Dispose(); stream = new MemoryStream(); FreeImage.SaveToStream(dib, stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags); FreeImage.Unload(dib); dib.SetNull(); #endif } else if (processed) { // image was rescaled, make new stream with rescaled bitmap #if USE_DIB || USE_FIB FREE_IMAGE_SAVE_FLAGS flags = FREE_IMAGE_SAVE_FLAGS.JPEG_SUBSAMPLING_444 | FREE_IMAGE_SAVE_FLAGS.JPEG_OPTIMIZE | FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYNORMAL; stream.Dispose(); stream = new MemoryStream(); #if USE_FIB fib.Save(stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags); fib.Dispose(); #else FreeImage.SaveToStream(dib, stream, FREE_IMAGE_FORMAT.FIF_JPEG, flags); FreeImage.Unload(dib); dib.SetNull(); #endif #else stream = GetBytesFromImage(bitmap); #endif // For now, images that were resized because they exceeded the maximum dimensions are not saved to the cache. } #if USE_DIB FreeImage.Unload(dib); dib.SetNull(); #elif USE_FIB fib.Dispose(); #elif USE_GDI if (bitmap != null) { bitmap.Dispose(); bitmap = null; } #endif // Always save thumbnails to the cache if (thumbnail) { ImageCache.Instance.SaveToCache(filename, stream, true); } else if (processed) { // Store rescaled and/or progressive jpegs in the cache for now. string processed_filename = string.Format("{0}-p{1}-processed.jpg", id, page); ImageCache.Instance.SaveToCache(processed_filename, stream, false); } stream.Seek(0, SeekOrigin.Begin); return(response.FromStream(stream, MimeTypes.GetMimeType(".jpg"))); } }
/// <summary> /// Return an image from a given filename /// </summary> /// <param name = "fileName"></param> /// <param name = "size"></param> /// <returns></returns> private Image GetImageFromFile(string fileName, out Size size) { FreeImageBitmap img = null; size = new Size(0, 0); try { img = new FreeImageBitmap(fileName); size = img.Size; // convert Image Size to 64 x 64 for display in the Imagelist img.Rescale(64, 64, FREE_IMAGE_FILTER.FILTER_BOX); } catch (Exception ex) { log.Error("File has invalid Picture: {0} {1}", fileName, ex.Message); } return img != null ? (Image)img : null; }
public void rescaleImage(FreeImageBitmap image, Size size, FREE_IMAGE_FILTER filter) { image.Rescale(size, filter); }
private IEnumerable <IdleStatus> createRender(int finalWidth, int finalHeight, int aaMode, bool showWatermark, bool transparentBG, Engine.Color backColor, Camera cloneCamera, Vector3 position, Vector3 lookAt, float minNearDistance, float nearPlaneWorld, float nearFarLength, ImageRendererProperties properties, Action <FreeImageBitmap> renderingCompletedCallback) { FreeImageBitmap bitmap = null; OgreSceneManager sceneManager = controller.CurrentScene.getDefaultSubScene().getSimElementManager <OgreSceneManager>(); if (sceneManager != null) { bool doGridRender; int backBufferWidth; int backBufferHeight; using (TexturePtr texture = createOgreTexture(finalWidth, finalHeight, aaMode, out doGridRender, out backBufferWidth, out backBufferHeight)) { if (texture != null) { using (HardwarePixelBufferSharedPtr pixelBuffer = texture.Value.getBuffer()) { RenderTexture renderTexture = pixelBuffer.Value.getRenderTarget(); Camera camera = sceneManager.SceneManager.createCamera("__PictureCamera"); camera.setLodBias(cloneCamera.getLodBias()); camera.setUseRenderingDistance(cloneCamera.getUseRenderingDistance()); camera.setNearClipDistance(cloneCamera.getNearClipDistance()); camera.setFarClipDistance(cloneCamera.getFarClipDistance()); camera.setPolygonMode(cloneCamera.getPolygonMode()); camera.setRenderingDistance(cloneCamera.getRenderingDistance()); camera.setProjectionType(cloneCamera.getProjectionType()); camera.setFOVy(cloneCamera.getFOVy()); camera.setAutoAspectRatio(false); camera.setAspectRatio((float)finalWidth / finalHeight); SceneNode node = sceneManager.SceneManager.createSceneNode("__PictureCameraNode"); node.attachObject(camera); node.setPosition(position); sceneManager.SceneManager.getRootSceneNode().addChild(node); camera.lookAt(lookAt); Viewport viewport = renderTexture.addViewport(camera, 1, 0.0f, 0.0f, 1.0f, 1.0f); if (properties.UseIncludePoint) { Matrix4x4 viewMatrix = camera.getViewMatrix(); Matrix4x4 projectionMatrix = camera.getProjectionMatrix(); float aspect = camera.getAspectRatio(); float fovy = camera.getFOVy() * 0.5f; float distance = SceneViewWindow.computeOffsetToIncludePoint(viewMatrix, projectionMatrix, properties.IncludePoint, aspect, fovy); Vector3 direction = (position - lookAt).normalized(); node.setPosition(position - (direction * distance)); camera.lookAt(lookAt); } if (transparentBG) { backColor.a = 0.0f; } ViewportBackground bgViewport = null; if (background != null) { bgViewport = new ViewportBackground("ImageRenderer", 0, background, renderTexture, false); bgViewport.BackgroundColor = backColor; bgViewport.Camera.setAutoAspectRatio(false); bgViewport.Camera.setAspectRatio((float)finalWidth / finalHeight); } viewport.setBackgroundColor(backColor); viewport.setOverlaysEnabled(false); viewport.setClearEveryFrame(false); if (properties.CustomizeCameraPosition != null) { properties.CustomizeCameraPosition(camera, viewport); } float near = CameraPositioner.computeNearClipDistance(camera.getDerivedPosition().length(), minNearDistance, nearPlaneWorld); camera.setNearClipDistance(near); camera.setFarClipDistance(near + nearFarLength); if (doGridRender) { IEnumerable <IdleStatus> process = gridRender(finalWidth * aaMode, finalHeight * aaMode, backBufferWidth, backBufferHeight, aaMode, renderTexture, camera, bgViewport != null ? bgViewport.Camera : null, transparentBG, backColor, (product) => { bitmap = product; }); foreach (IdleStatus idleStatus in process) { yield return(idleStatus); } } else { bitmap = simpleRender(backBufferWidth, backBufferHeight, aaMode, transparentBG, backColor, renderTexture); } if (showWatermark && LoadLogo != null) { using (FreeImageBitmap logo = LoadLogo()) { float imageFinalHeight = bitmap.Height * 0.0447f; float scale = imageFinalHeight / logo.Height; float imageFinalWidth = logo.Width * scale; if (imageFinalWidth > bitmap.Width) { imageFinalWidth = bitmap.Width; scale = imageFinalWidth / logo.Width; imageFinalHeight = logo.Height * scale; } logo.Rescale((int)imageFinalWidth, (int)imageFinalHeight, FREE_IMAGE_FILTER.FILTER_BILINEAR); //Have to composite the logo image first. using (FreeImageBitmap fullImageCorner = bitmap.Copy(0, bitmap.Height - (int)imageFinalHeight, (int)imageFinalWidth, bitmap.Height)) { fullImageCorner.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP); logo.Composite(false, null, fullImageCorner); } bitmap.Paste(logo, 0, bitmap.Height - (int)imageFinalHeight, int.MaxValue); } } renderTexture.destroyViewport(viewport); if (bgViewport != null) { bgViewport.Dispose(); } sceneManager.SceneManager.getRootSceneNode().removeChild(node); sceneManager.SceneManager.destroySceneNode(node); sceneManager.SceneManager.destroyCamera(camera); TextureManager.getInstance().remove(texture); } } else { //An error making the render texture. Log it and return the error image. Log.Error("Could not render image. Returning placeholder image. Reason: Could not create valid render to texture target."); bitmap = new FreeImageBitmap(finalWidth, finalHeight); bitmap.FillBackground(new RGBQUAD() { rgbRed = 255 }); } } } renderingCompletedCallback(bitmap); yield break; }
public void updateThumbnail(bool forceUpdateSceneThumb = false) { Dictionary <RmlEditorViewInfo, LayoutContainer> layoutPositions = new Dictionary <RmlEditorViewInfo, LayoutContainer>(); if (slideEditorController.ResourceProvider != null) { //Setup a LayoutChain to mimic the main one. LayoutChain layoutChain = new LayoutChain(); layoutChain.addLink(new PopupAreaChainLink(GUILocationNames.ContentAreaPopup), true); layoutChain.addLink(new BorderLayoutNoAnimationChainLink(GUILocationNames.ContentArea), true); IntSize2 thumbTotalSize = new IntSize2(SlideImageManager.ThumbWidth, SlideImageManager.ThumbHeight); FreeImageBitmap thumb = slideEditorController.SlideImageManager.createThumbBitmap(slide); layoutChain.SuppressLayout = true; LayoutContainer sceneContainer = new NullLayoutContainer(thumbTotalSize); layoutChain.addContainer(new BorderLayoutElementName(GUILocationNames.ContentArea, BorderLayoutLocations.Center), sceneContainer, null); foreach (var editor in rmlEditors.Values) { if (editor.Component != null) { float sizeRatio = (float)SlideImageManager.ThumbHeight / editor.Component.ViewHost.Container.RigidParentWorkingSize.Height; IntSize2 size = (IntSize2)(editor.Component.ViewHost.Container.DesiredSize * sizeRatio); NullLayoutContainer container = new NullLayoutContainer(size); layoutPositions.Add(editor, container); layoutChain.addContainer(editor.View.ElementName, container, null); } } layoutChain.SuppressLayout = false; layoutChain.WorkingSize = thumbTotalSize; layoutChain.Location = new IntVector2(0, 0); layoutChain.layout(); //Render thumbnail, Start with the scene IntVector2 sceneThumbPosition = sceneContainer.Location; String sceneThumbFile = slide.SceneThumbName; if (forceUpdateSceneThumb) { slideEditorController.SlideImageManager.addUnsavedSceneThumb(slide, renderSceneThumbnail()); } SceneThumbInfo sceneThumbInfo = slideEditorController.SlideImageManager.loadThumbSceneBitmap(slide, renderSceneThumbnail); IntSize2 centerSize = sceneContainer.WorkingSize; RectangleF destRect = new RectangleF(sceneThumbPosition.x, sceneThumbPosition.y, centerSize.Width, centerSize.Height); thumb.FillBackground(new RGBQUAD(FreeImageAPI.Color.FromArgb(sceneThumbInfo.Color.toARGB()))); int requiredWidth = (sceneThumbInfo.SceneThumb.Width - ((sceneThumbInfo.SceneThumb.Width - sceneThumbInfo.IncludeX) * 2)); int requiredHeight = (sceneThumbInfo.SceneThumb.Height - (sceneThumbInfo.IncludeY * 2)); int sceneThumbWidth = sceneThumbInfo.SceneThumb.Width; int sceneThumbHeight = sceneThumbInfo.SceneThumb.Height; int sceneThumbHalfWidth = sceneThumbWidth / 2; int sceneThumbHalfHeight = sceneThumbHeight / 2; float requiredHeightWidthRatio = (float)requiredHeight / requiredWidth; float centerHeightWidthRatio = (float)centerSize.Height / centerSize.Width; float srcWidth = requiredWidth; float srcHeight = requiredHeight; if (requiredHeightWidthRatio < centerHeightWidthRatio) //Compare ratios between our source required area and the destination { //Use the full required width, add height from source image //Convert the center size to the same size ratio as the required size float sizeRatio = (float)requiredWidth / centerSize.Width; srcHeight = centerSize.Height * sizeRatio; if (srcHeight > sceneThumbHeight) //Stretch out the image as much as possible, limiting by the size of the scene thumb if needed. { srcHeight = sceneThumbHeight; } float destHeight = srcHeight / sizeRatio; destRect = new RectangleF(destRect.Left, destRect.Height / 2 + destRect.Top - destHeight / 2, destRect.Width, destHeight); //Make a dest rect that takes as much image as it can } else { //Use the full required height, add width from source image float sizeRatio = (float)requiredHeight / centerSize.Height; srcWidth = centerSize.Width * sizeRatio; if (srcWidth > sceneThumbWidth) { srcWidth = sceneThumbWidth; } float destWidth = srcWidth / sizeRatio; destRect = new RectangleF(destRect.Width / 2 + destRect.Left - destWidth / 2, destRect.Top, destWidth, destRect.Height); } RectangleF srcRect = new RectangleF(sceneThumbHalfWidth - srcWidth / 2, sceneThumbHalfHeight - srcHeight / 2, srcWidth, srcHeight); using (FreeImageBitmap resizedSceneThumb = sceneThumbInfo.SceneThumb.Copy((int)srcRect.X, (int)srcRect.Y, (int)srcRect.Right, (int)srcRect.Bottom)) { resizedSceneThumb.Rescale((int)destRect.Width, (int)destRect.Height, FREE_IMAGE_FILTER.FILTER_BILINEAR); thumb.Paste(resizedSceneThumb, (int)destRect.X, (int)destRect.Y, int.MaxValue); } //Render all panels foreach (var editor in rmlEditors.Values) { if (editor.Component != null) { LayoutContainer container; if (layoutPositions.TryGetValue(editor, out container)) { Rectangle panelThumbPos = new Rectangle(container.Location.x, container.Location.y, container.WorkingSize.Width, container.WorkingSize.Height); editor.Component.writeToGraphics(thumb, panelThumbPos); } } } slideEditorController.SlideImageManager.thumbnailUpdated(slide); } }
private void createImage(String guidStr, FreeImageBitmap image, out IntSize2 finalSize) { FreeImageBitmap resizedImage = null; try { //resize the image if it does not match Size addImageSize = image.Size; if (addImageSize.Width != imageSize.Width || addImageSize.Height != imageSize.Height) { Rectangle destRect; switch (ResizeMode) { case ImageResizeMode.KeepAspect: int width = 8; float aspect = (float)addImageSize.Height / addImageSize.Width; int height = (int)((float)imageSize.Width * aspect); if (height < imageSize.Height) { width = imageSize.Width; } else { aspect = (float)image.Width / image.Height; height = imageSize.Height; width = (int)((float)imageSize.Height * aspect); } destRect = new Rectangle(0, 0, width, height); break; default: destRect = new Rectangle(0, 0, imageSize.Width, imageSize.Height); break; } resizedImage = new FreeImageBitmap(image); resizedImage.Rescale(destRect.Width, destRect.Height, FREE_IMAGE_FILTER.FILTER_BILINEAR); image = resizedImage; } MemoryStream imageStream = null; try { imageStream = new MemoryStream(); image.Save(imageStream, FREE_IMAGE_FORMAT.FIF_PNG); memoryArchive.addMemoryStreamResource(guidStr + ".png", imageStream); String xmlString = String.Format(resourceXML, guidStr, name + guidStr + ".png", imageSize.Width, imageSize.Height); memoryArchive.addMemoryStreamResource(guidStr + ".xml", new MemoryStream(ASCIIEncoding.UTF8.GetBytes(xmlString))); ResourceManager.Instance.load(name + guidStr + ".xml"); } catch (Exception ex) { Logging.Log.Error("Exception saving image to atlas {0}", ex.Message); if (imageStream != null) { imageStream.Dispose(); } } finalSize = new IntSize2(image.Width, image.Height); } finally { //Dispose the image if it was resized if (resizedImage != null) { resizedImage.Dispose(); } } }
private IEnumerable <IdleStatus> gridRender(int width, int height, int backBufferWidth, int backBufferHeight, int aaMode, RenderTexture renderTexture, Camera camera, Camera backgroundCamera, bool transparentBG, Engine.Color bgColor, Action <FreeImageBitmap> renderingCompletedCallback) { float originalLeft, originalRight, originalTop, originalBottom; camera.getFrustumExtents(out originalLeft, out originalRight, out originalTop, out originalBottom); int imageCountWidth = width % backBufferWidth == 0 ? width / backBufferWidth : width / backBufferWidth + 1; int imageCountHeight = height % backBufferHeight == 0 ? height / backBufferHeight : height / backBufferHeight + 1; float gridStepHoriz = (originalRight * 2) / imageCountWidth; float gridStepVert = (originalTop * 2) / imageCountHeight; float bgOriginalLeft = 0, bgOriginalRight = 0, bgOriginalTop = 0, bgOriginalBottom = 0, bgGridStepHoriz = 0, bgGridStepVert = 0; if (backgroundCamera != null) { backgroundCamera.getFrustumExtents(out bgOriginalLeft, out bgOriginalRight, out bgOriginalTop, out bgOriginalBottom); bgGridStepHoriz = (bgOriginalRight * 2) / imageCountWidth; bgGridStepVert = (bgOriginalTop * 2) / imageCountHeight; } int imageStepHoriz = backBufferWidth; int imageStepVert = backBufferHeight; int finalWidth = width / aaMode; int finalHeight = height / aaMode; int imageStepHorizSmall = finalWidth / imageCountWidth; int imageStepVertSmall = finalHeight / imageCountHeight; float left, right, top, bottom; float bgLeft, bgRight, bgTop, bgBottom; int totalSS = imageCountWidth * imageCountHeight; String updateString = "Rendering piece {0} of " + totalSS; OgrePlugin.PixelFormat format = OgrePlugin.PixelFormat.PF_A8R8G8B8; FreeImageAPI.PixelFormat bitmapFormat = FreeImageAPI.PixelFormat.Format32bppRgb; if (transparentBG) { bitmapFormat = FreeImageAPI.PixelFormat.Format32bppArgb; } Rectangle destRect = new Rectangle(); Rectangle srcRect = new Rectangle(0, 0, imageStepHoriz, imageStepVert); FreeImageBitmap fullBitmap = new FreeImageBitmap(finalWidth, finalHeight, bitmapFormat); using (FreeImageBitmap pieceBitmap = new FreeImageBitmap(imageStepHoriz, imageStepVert, bitmapFormat)) { bool aaOn = aaMode > 1; Rectangle scalarRectangle = new Rectangle(); if (aaOn) { scalarRectangle = new Rectangle(0, 0, imageStepHorizSmall, imageStepVertSmall); } for (int i = 0; i < totalSS; ++i) { int y = i / imageCountWidth; int x = i - y * imageCountWidth; left = originalLeft + gridStepHoriz * x; right = left + gridStepHoriz; top = originalTop - gridStepVert * y; bottom = top - gridStepVert; camera.setFrustumExtents(left, right, top, bottom); if (backgroundCamera != null) { bgLeft = bgOriginalLeft + bgGridStepHoriz * x; bgRight = bgLeft + bgGridStepHoriz; bgTop = bgOriginalTop - bgGridStepVert * y; bgBottom = bgTop - bgGridStepVert; backgroundCamera.setFrustumExtents(bgLeft, bgRight, bgTop, bgBottom); } Root.getSingleton().clearEventTimes(); renderTexture.getViewport(0).clear(FrameBufferType.FBT_COLOUR | FrameBufferType.FBT_DEPTH | FrameBufferType.FBT_STENCIL, bgColor); renderTexture.update(); pieceBitmap.copyFromRenderTarget(renderTexture, format); destRect.X = x * imageStepHorizSmall; destRect.Y = y * imageStepVertSmall; destRect.Width = imageStepHorizSmall; destRect.Height = imageStepVertSmall; if (aaOn) { using (FreeImageBitmap scaled = new FreeImageBitmap(pieceBitmap)) { scaled.Rescale(scalarRectangle.Width, scalarRectangle.Height, FREE_IMAGE_FILTER.FILTER_BILINEAR); fullBitmap.Paste(scaled, destRect.X, destRect.Y, int.MaxValue); } } else { fullBitmap.Paste(pieceBitmap, destRect.X, destRect.Y, int.MaxValue); } if (imageRendererProgress != null) { imageRendererProgress.update((uint)(((float)(i + 1) / totalSS) * 100.0f), String.Format(updateString, i + 1)); if (imageRendererProgress.Cancel) { break; } } yield return(IdleStatus.Ok); } } renderTexture.getViewport(0).setOverlaysEnabled(true); renderingCompletedCallback(fullBitmap); yield break; }
/// <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(); } }