//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 static FREE_IMAGE_FILTER ParseResizeAlgorithm(string sf, FREE_IMAGE_FILTER defaultValue, out bool valid) { FREE_IMAGE_FILTER filter = defaultValue; valid = true; if ("bicubic".Equals(sf, StringComparison.OrdinalIgnoreCase)) filter = FREE_IMAGE_FILTER.FILTER_BICUBIC; else if ("bilinear".Equals(sf, StringComparison.OrdinalIgnoreCase)) filter = FREE_IMAGE_FILTER.FILTER_BILINEAR; else if ("box".Equals(sf, StringComparison.OrdinalIgnoreCase)) filter = FREE_IMAGE_FILTER.FILTER_BOX; else if ("bspline".Equals(sf, StringComparison.OrdinalIgnoreCase)) filter = FREE_IMAGE_FILTER.FILTER_BSPLINE; else if ("catmullrom".Equals(sf, StringComparison.OrdinalIgnoreCase)) filter = FREE_IMAGE_FILTER.FILTER_CATMULLROM; else if ("lanczos".Equals(sf, StringComparison.OrdinalIgnoreCase)) filter = FREE_IMAGE_FILTER.FILTER_LANCZOS3; else valid = false; return filter; }
private static TimeSpan DoTest(FREE_IMAGE_FILTER filter, FREE_IMAGE_SAVE_FLAGS quality) { foreach (string s in Directory.GetFiles(@"..\..\..\testdata\pix", "*small*")) { //File.Delete(s); } DateTime start = DateTime.Now; foreach (string s in Directory.GetFiles(@"..\..\..\testdata\pix", "test*jpg")) { var fin = new FileInfo(s); var fout = new FileInfo(Path.Combine(fin.DirectoryName, string.Format("t{0}_small_{1}_{2}.jpg", fin.NameWithoutExtension(), filter, quality))); ImageWorker.ShrinkImageFI(fin, fout, new Size(400, 400), FREE_IMAGE_FORMAT.FIF_JPEG, filter, quality, true); Console.WriteLine("{0} -> {1}", fin.Name, fout.Name); } TimeSpan ts = DateTime.Now.Subtract(start); string d = Directory.GetCurrentDirectory(); return ts; }
private static TimeSpan DoTest(FREE_IMAGE_FILTER filter, FREE_IMAGE_SAVE_FLAGS quality) { foreach (string s in Directory.GetFiles(@"..\..\..\testdata\pix", "*small*")) { //File.Delete(s); } DateTime start = DateTime.Now; foreach (string s in Directory.GetFiles(@"..\..\..\testdata\pix", "test*jpg")) { var fin = new FileInfo(s); var fout = new FileInfo(Path.Combine(fin.DirectoryName, string.Format("t{0}_small_{1}_{2}.jpg", fin.NameWithoutExtension(), filter, quality))); ImageWorker.ShrinkImageFI(fin, fout, new Size(400, 400), FREE_IMAGE_FORMAT.FIF_JPEG, filter, quality, true); Console.WriteLine("{0} -> {1}", fin.Name, fout.Name); } TimeSpan ts = DateTime.Now.Subtract(start); string d = Directory.GetCurrentDirectory(); return(ts); }
public static FREE_IMAGE_FILTER ParseResizeAlgorithm(string sf, FREE_IMAGE_FILTER defaultValue, out bool valid) { FREE_IMAGE_FILTER filter = defaultValue; valid = true; if ("bicubic".Equals(sf, StringComparison.OrdinalIgnoreCase)) { filter = FREE_IMAGE_FILTER.FILTER_BICUBIC; } else if ("bilinear".Equals(sf, StringComparison.OrdinalIgnoreCase)) { filter = FREE_IMAGE_FILTER.FILTER_BILINEAR; } else if ("box".Equals(sf, StringComparison.OrdinalIgnoreCase)) { filter = FREE_IMAGE_FILTER.FILTER_BOX; } else if ("bspline".Equals(sf, StringComparison.OrdinalIgnoreCase)) { filter = FREE_IMAGE_FILTER.FILTER_BSPLINE; } else if ("catmullrom".Equals(sf, StringComparison.OrdinalIgnoreCase)) { filter = FREE_IMAGE_FILTER.FILTER_CATMULLROM; } else if ("lanczos".Equals(sf, StringComparison.OrdinalIgnoreCase)) { filter = FREE_IMAGE_FILTER.FILTER_LANCZOS3; } else { valid = false; } return(filter); }
public static extern uint Rescale(uint dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
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"))); } }
public static FIBITMAP GetShrinkedDIB(FIBITMAP dib, Size nuSize, FREE_IMAGE_FILTER filter) { return FreeImage.Rescale(dib, nuSize.Width, nuSize.Height, filter); }
public static void ShrinkImageFI(FIBITMAP dib, FileInfo fileOut, Size nuSize, FREE_IMAGE_FILTER filter, FREE_IMAGE_SAVE_FLAGS savequality) { FIBITMAP dibsmall = GetShrinkedDIB(dib, nuSize, filter); SaveJPGImageHandle(dibsmall, fileOut, savequality); CleanUpResources(dibsmall); }
protected override RequestedAction PreRenderImage(ImageState s) { //Skip this when we are doing simulations if (s.destGraphics == null) { return(RequestedAction.None); } string sf = s.settings["fi.scale"]; if (string.IsNullOrEmpty(sf)) { return(RequestedAction.None); } bool validAlg = false; FREE_IMAGE_FILTER filter = ParseResizeAlgorithm(sf, FREE_IMAGE_FILTER.FILTER_CATMULLROM, out validAlg); if (!validAlg) { throw new ImageProcessingException("The specified resizing filter '" + sf + "' did not match bicubic, bilinear, box, bspline, catmullrom, or lanczos."); } //Set copy attributes s.copyAttibutes.SetWrapMode(WrapMode.TileFlipXY); //The minimum dimensions of the temporary bitmap. SizeF targetSize = PolygonMath.getParallelogramSize(s.layout["image"]); targetSize = new SizeF((float)Math.Ceiling(targetSize.Width), (float)Math.Ceiling(targetSize.Height)); s.ApplyCropping(); s.EnsurePreRenderBitmap(); //The size of the temporary bitmap. //We want it larger than the size we'll use on the final copy, so we never upscale it //- but we also want it as small as possible so processing is fast. SizeF tempSize = PolygonMath.ScaleOutside(targetSize, s.copyRect.Size); int tempWidth = (int)Math.Ceiling(tempSize.Width); int tempHeight = (int)Math.Ceiling(tempSize.Height); FIBITMAP src = FIBITMAP.Zero; FIBITMAP midway = FIBITMAP.Zero; try { var oldbit = s.preRenderBitmap ?? s.sourceBitmap; //Crop if needed, Convert, scale, then convert back. src = FreeImage.CreateFromBitmap(oldbit); midway = FreeImage.Rescale(src, tempWidth, tempHeight, filter); FreeImage.UnloadEx(ref src); //Clear the old pre-rendered image if needed if (s.preRenderBitmap != null) { s.preRenderBitmap.Dispose(); } //Reassign the pre-rendered image s.preRenderBitmap = FreeImage.GetBitmap(midway); s.copyRect = new RectangleF(0, 0, s.preRenderBitmap.Width, s.preRenderBitmap.Height); FreeImage.UnloadEx(ref midway); s.preRenderBitmap.MakeTransparent(); } finally { if (!src.IsNull) { FreeImage.UnloadEx(ref src); } if (!midway.IsNull) { FreeImage.UnloadEx(ref midway); } } return(RequestedAction.Cancel); }
public static extern FIBITMAP Rescale(FIBITMAP dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
public void Bake() { // Validate Project Platform if (!Unity3D2Babylon.Tools.ValidateProjectPlatform()) { return; } try { string inputFile = AssetDatabase.GetAssetPath(convertCube); string inputExt = Path.GetExtension(inputFile); if (cubemapTool == BabylonCubemapTool.ReflectionProbes) { if (inputExt.Equals(".hdr", StringComparison.OrdinalIgnoreCase) || inputExt.Equals(".exr", StringComparison.OrdinalIgnoreCase)) { ExporterWindow.ReportProgress(1, "Baking cubemap reflection probe... This may take a while."); string outputFile = inputFile.Replace(inputExt, "Probe.hdr"); int reflectionResolution = (int)reflectionType; FREE_IMAGE_FORMAT srcType = FREE_IMAGE_FORMAT.FIF_HDR; if (inputExt.Equals(".hdr", StringComparison.OrdinalIgnoreCase)) { srcType = FREE_IMAGE_FORMAT.FIF_HDR; } else if (inputExt.Equals(".exr", StringComparison.OrdinalIgnoreCase)) { srcType = FREE_IMAGE_FORMAT.FIF_EXR; } FREE_IMAGE_FILTER rescaleFilter = FREE_IMAGE_FILTER.FILTER_LANCZOS3; int rescaleWidth = reflectionResolution * 4; int rescaleHeight = rescaleWidth / 2; FileStream destStream = new FileStream(outputFile, FileMode.Create, FileAccess.Write); FileStream sourceStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read); try { Tools.ConvertFreeImage(sourceStream, srcType, destStream, FREE_IMAGE_FORMAT.FIF_HDR, FREE_IMAGE_TYPE.FIT_UNKNOWN, true, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, FREE_IMAGE_LOAD_FLAGS.DEFAULT, FREE_IMAGE_SAVE_FLAGS.DEFAULT, 0.0, false, false, rescaleWidth, rescaleHeight, rescaleFilter); } catch (Exception ex) { UnityEngine.Debug.LogException(ex); } finally { destStream.Close(); sourceStream.Close(); } if (System.IO.File.Exists(outputFile)) { AssetDatabase.ImportAsset(outputFile, ImportAssetOptions.ForceUpdate); var importTool = new BabylonTextureImporter(outputFile); importTool.textureImporter.textureShape = TextureImporterShape.TextureCube; importTool.textureImporter.isReadable = true; importTool.ForceUpdate(); } } else { ExporterWindow.ShowMessage("You must select a high dynamic range cubemap"); } } else if (cubemapTool == BabylonCubemapTool.CubemapSplitter) { ExporterWindow.ReportProgress(1, "Baking cubemap texture faces... This may take a while."); bool jpeg = (imageFormat == BabylonImageFormat.JPEG); string faceExt = (jpeg) ? ".jpg" : ".png"; var splitterOpts = new BabylonSplitterOptions(); var outputFile = inputFile.Replace(inputExt, faceExt); Tools.ExportCubemap(convertCube, outputFile, imageFormat, splitterOpts); if (createSkyboxMaterial == true) { ExporterWindow.ReportProgress(1, "Generating skybox material assets... This may take a while."); AssetDatabase.Refresh(); Material skyboxMaterial = new Material(Shader.Find("Mobile/Skybox")); if (skyboxMaterial != null) { string frontFilename = outputFile.Replace(faceExt, ("_pz" + faceExt)); AssetDatabase.ImportAsset(frontFilename, ImportAssetOptions.ForceUpdate); Texture2D frontTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(frontFilename, typeof(Texture2D)); if (frontTexture != null) { skyboxMaterial.SetTexture("_FrontTex", frontTexture); } string backFilename = outputFile.Replace(faceExt, ("_nz" + faceExt)); AssetDatabase.ImportAsset(backFilename, ImportAssetOptions.ForceUpdate); Texture2D backTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(backFilename, typeof(Texture2D)); if (backTexture != null) { skyboxMaterial.SetTexture("_BackTex", backTexture); } string leftFilename = outputFile.Replace(faceExt, ("_px" + faceExt)); AssetDatabase.ImportAsset(leftFilename, ImportAssetOptions.ForceUpdate); Texture2D leftTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(leftFilename, typeof(Texture2D)); if (leftTexture != null) { skyboxMaterial.SetTexture("_LeftTex", leftTexture); } string rightFilename = outputFile.Replace(faceExt, ("_nx" + faceExt)); AssetDatabase.ImportAsset(rightFilename, ImportAssetOptions.ForceUpdate); Texture2D rightTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(rightFilename, typeof(Texture2D)); if (rightTexture != null) { skyboxMaterial.SetTexture("_RightTex", rightTexture); } string upFilename = outputFile.Replace(faceExt, ("_py" + faceExt)); AssetDatabase.ImportAsset(upFilename, ImportAssetOptions.ForceUpdate); Texture2D upTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(upFilename, typeof(Texture2D)); if (upTexture != null) { skyboxMaterial.SetTexture("_UpTex", upTexture); } string downFilename = outputFile.Replace(faceExt, ("_ny" + faceExt)); AssetDatabase.ImportAsset(downFilename, ImportAssetOptions.ForceUpdate); Texture2D downTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(downFilename, typeof(Texture2D)); if (downTexture != null) { skyboxMaterial.SetTexture("_DownTex", downTexture); } string outputMaterialName = Path.GetFileNameWithoutExtension(inputFile); string outputMaterialPath = Path.GetDirectoryName(inputFile); string outputMaterialFile = outputMaterialPath + "/" + outputMaterialName + ".mat"; AssetDatabase.CreateAsset(skyboxMaterial, outputMaterialFile); } else { throw new Exception("Failed to create 'Mobile/Skybox' material"); } } } } catch (Exception ex) { UnityEngine.Debug.LogException(ex); } finally { ExporterWindow.ReportProgress(1, "Refresing assets database..."); AssetDatabase.Refresh(); } ExporterWindow.ReportProgress(1, "Cubemap conversion complete."); EditorUtility.ClearProgressBar(); if (this.keepGeneratorOpen) { ExporterWindow.ShowMessage("Cubemap optimzation complete.", "Babylon.js"); } else { this.Close(); } }
public static FIBITMAP GetShrinkedDIB(FIBITMAP dib, Size nuSize, FREE_IMAGE_FILTER filter) { return(FreeImage.Rescale(dib, nuSize.Width, nuSize.Height, filter)); }
public static void ShrinkImageFI(FIBITMAP dib, FileInfo fileOut, Size nuSize, FREE_IMAGE_FILTER filter, FREE_IMAGE_SAVE_FLAGS savequality) { FIBITMAP dibsmall = GetShrinkedDIB(dib, nuSize, filter); SaveJPGImageHandle(dibsmall, fileOut, savequality); CleanUpResources(dibsmall); }
public static FIBITMAP?ShrinkImageFI(FileInfo fileIn, FileInfo fileOut, Size nuSize, FREE_IMAGE_FORMAT saveFormat, FREE_IMAGE_FILTER filter, FREE_IMAGE_SAVE_FLAGS savequality, bool cleanup) { FIBITMAP?dib = GetJPGImageHandle(fileIn); if (dib != null) { FIBITMAP ddib = (FIBITMAP)dib; ShrinkImageFI(ddib, fileOut, nuSize, filter, savequality); if (cleanup) { CleanUpResources(ddib); } } return(dib); }
public void Transform(Schema.SkinFile.Attachment.Transform trnsfrm) { if (dib.IsNull) { return; } if (FreeImage.GetWidth(dib) <= 1 || FreeImage.GetHeight(dib) <= 1) { return; } FREE_IMAGE_FILTER filter = FREE_IMAGE_FILTER.FILTER_BSPLINE; if (trnsfrm.scaleFilter != null) { switch (trnsfrm.scaleFilter.ToUpper()) { case "BOX": filter = FREE_IMAGE_FILTER.FILTER_BOX; break; case "BICUBIC": filter = FREE_IMAGE_FILTER.FILTER_BICUBIC; break; case "BILINEAR": filter = FREE_IMAGE_FILTER.FILTER_BILINEAR; break; case "BSPLINE": filter = FREE_IMAGE_FILTER.FILTER_BSPLINE; break; case "CATMULLROM": filter = FREE_IMAGE_FILTER.FILTER_CATMULLROM; break; case "LANCZOS3": filter = FREE_IMAGE_FILTER.FILTER_LANCZOS3; break; } } RectangleF originalDimensions, rotationDimensions; GraphicsUnit pageUnit = GraphicsUnit.Pixel; dib = FreeImage.Rescale(dib, (int)(FreeImage.GetWidth(dib) * trnsfrm.scaleX), (int)(FreeImage.GetHeight(dib) * trnsfrm.scaleY), filter); originalDimensions = FreeImage.GetBitmap(dib).GetBounds(ref pageUnit); RGBQUAD bgColor = new RGBQUAD(); bgColor.rgbRed = 0x00; bgColor.rgbGreen = 0x00; bgColor.rgbBlue = 0x00; bgColor.rgbReserved = 0x00; // TODO: вычесть из положения разницу между оригинальными размерами и размерами после поворота (по крайней мере сверху) //int size = (int)(trnsfrm.x > 0 ? trnsfrm.x : 0) + (int)(trnsfrm.y > 0 ? trnsfrm.y : 0); //trnsfrm.angle = -45; /* * double cos = Math.Cos(-trnsfrm.angle * Math.PI / 180), sin = Math.Sin(-trnsfrm.angle * Math.PI / 180); * Point[] points = new Point[4] { * new Point((int)(originalDimensions.Width / 2), (int)(originalDimensions.Height / 2)), // top left //(int)(originalDimensions.Width / 2 * cos - originalDimensions.Height / 2 * sin), (int)(originalDimensions.Width / 2 * sin + originalDimensions.Height / 2 * cos)), * new Point((int)(originalDimensions.Width / 2), (int)(-originalDimensions.Height / 2)), // top right * new Point((int)(-originalDimensions.Width / 2), (int)(originalDimensions.Height / 2)), // bottom left * new Point((int)(-originalDimensions.Width / 2), (int)(-originalDimensions.Height / 2)) // bottom right * }; * for (int i = 0; i < points.Length; i++) * { * points[i].X = (int)(points[i].X * cos - points[i].Y * sin); * points[i].Y = (int)(points[i].X * sin + points[i].Y * cos); * } * int maxRight = points[0].X, maxBottom = points[0].Y; * for (int i = 0; i < points.Length; i++) * { * if (points[i].X > maxRight) maxRight = points[i].X; * if (points[i].Y > maxBottom) maxBottom = points[i].Y; * } * * Console.WriteLine(points[0]); * Console.WriteLine(points[1]); * Console.WriteLine(points[2]); * Console.WriteLine(points[3]); * * Console.WriteLine(maxRight); * Console.WriteLine(maxBottom); * int rightOffset = (int)(maxRight - originalDimensions.Width / 2), bottomOffset = (int)(maxBottom - originalDimensions.Height / 2); * Console.WriteLine(rightOffset); * Console.WriteLine(bottomOffset); */ /* * Console.WriteLine(originalDimensions); * Console.WriteLine(originalDimensions.Width / 2 * Math.Cos(trnsfrm.angle * Math.PI / 180) - originalDimensions.Height / 2 * Math.Sin(trnsfrm.angle * Math.PI / 180)); * Console.WriteLine(originalDimensions.Width / 2 * Math.Sin(trnsfrm.angle * Math.PI / 180) + originalDimensions.Height / 2 * Math.Cos(trnsfrm.angle * Math.PI / 180)); */ dib = FreeImage.Rotate <RGBQUAD>(dib, -trnsfrm.angle, bgColor); rotationDimensions = FreeImage.GetBitmap(dib).GetBounds(ref pageUnit); dib = FreeImage.EnlargeCanvas <RGBQUAD>(dib, 0, 0, (int)(trnsfrm.x > 0 ? trnsfrm.x : 0), // + rightOffset,//(int)(originalDimensions.Width / 2 * Math.Cos(trnsfrm.angle * Math.PI / 180) - originalDimensions.Height / 2 * Math.Sin(trnsfrm.angle * Math.PI / 180) - originalDimensions.Width / 2) + 2, (int)(trnsfrm.y > 0 ? trnsfrm.y : 0), // + bottomOffset,//(int)(originalDimensions.Width / 2 * Math.Sin(trnsfrm.angle * Math.PI / 180) + originalDimensions.Height / 2 * Math.Cos(trnsfrm.angle * Math.PI / 180)), bgColor, FREE_IMAGE_COLOR_OPTIONS.FICO_RGBA ); //dib = FreeImage.RotateEx(dib, 0, trnsfrm.x, trnsfrm.y, 0, 0, true); //dib = FreeImage.Rotate<RGBQUAD>(dib, trnsfrm.angle, bgColor); //dib = FreeImage.RotateEx(dib, 0, trnsfrm.x, trnsfrm.y, originalDimensions.Width / 2, originalDimensions.Height / 2, true); dib = FreeImage.RotateEx(dib, 0, trnsfrm.x, trnsfrm.y, 0, 0, true); dib = FreeImage.EnlargeCanvas <RGBQUAD>(dib, (int)(rotationDimensions.Width - originalDimensions.Width) / -2, (int)(rotationDimensions.Height - originalDimensions.Height) / -2, 0, 0, bgColor, FREE_IMAGE_COLOR_OPTIONS.FICO_RGBA ); //dib = FreeImage.RotateEx(dib, 0, trnsfrm.x - (rotationDimensions.Width - originalDimensions.Width) / 2, trnsfrm.y - (rotationDimensions.Height - originalDimensions.Height) / 2, 0, 0, true); //dib = FreeImage.RotateEx(dib, 0, trnsfrm.x, trnsfrm.y, 0, 0, true); }
private static extern FIBITMAP RescaleWindows(FIBITMAP dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
public static extern IntPtr Rescale(IntPtr dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
//private unsafe byte getColor(int x, int y, FreeImageBitmap src, Channel channel) //{ // int bpp = 4; // if (src.PixelFormat == FreeImageAPI.PixelFormat.Format24bppRgb) // { // bpp = 3; // } // byte* pixel = (byte*)src.Bits.ToPointer(); // pixel += (src.Pitch * (src.Height - y - 1) + x) * bpp; // switch (channel) // { // case Channel.Alpha: // return pixel[3]; // case Channel.Red: // return pixel[2]; // case Channel.Green: // return pixel[1]; // case Channel.Blue: // return pixel[0]; // } // throw new NotSupportedException(); //Won't get here //} private async Task saveUncompressed(String sourceFile, String destFile, bool lossless, FREE_IMAGE_FILTER filter, ImagePageSizeStrategy pageSizeStrategy, Action <FreeImageBitmap> afterResize = null) { await Task.Run(() => { if ((outputFormats & OutputFormats.Uncompressed) != 0) { Log.Info("Creating paged data for {0}", sourceFile); using (FreeImageBitmap source = FreeImageBitmap.FromFile(sourceFile)) { using (var stream = File.Open(String.Format(PagedTextureNameFormat, destFile), FileMode.Create, FileAccess.ReadWrite)) { PagedImage.fromBitmap(source, 128, 1, stream, PagedImage.ImageType.WEBP, maxSize, lossless, filter, pageSizeStrategy, afterResize); } } } }); }
public BitmapContent GetScaledBitmapContent(int width, int height, FREE_IMAGE_FILTER filter = FREE_IMAGE_FILTER.FILTER_CATMULLROM) { FIBITMAP bitmap = FreeImage.Rescale(_bitmap, width, height, filter); return(new BitmapContent(width, height, ImageType, bitmap)); }
public void rescaleImage(FreeImageBitmap image, Size size, FREE_IMAGE_FILTER filter) { image.Rescale(size, filter); }
/// <summary> /// Create a paged image from a FreeImageBitmap instance, note that this function is destructive /// to the passed in FreeImageBitmap since it will resize it while creating all the mip levels /// for the paged image. However, you will still need to dispose the image you pass in, this class /// makes a copy while destroying the image, but does not take ownership of the original. /// </summary> /// <param name="image">The image to extract pages from.</param> /// <param name="pageSize">The size of the pages to extract.</param> public static void fromBitmap(FreeImageBitmap image, int pageSize, int padding, Stream stream, ImageType imageType, int maxSize, bool lossless, FREE_IMAGE_FILTER filter, ImagePageSizeStrategy pageSizeStrategy, Action <FreeImageBitmap> afterResize = null) { stream.Seek(HeaderSize, SeekOrigin.Begin); //Leave some space for the header if (image.Width > maxSize) { Logging.Log.Info("Image size {0} was too large, resizing to {1}", image.Width, maxSize); pageSizeStrategy.rescaleImage(image, new Size(maxSize, maxSize), filter); } PagedImage pagedImage = new PagedImage(); int padding2x = padding * 2; FREE_IMAGE_FORMAT outputFormat; FREE_IMAGE_SAVE_FLAGS saveFlags = FREE_IMAGE_SAVE_FLAGS.DEFAULT; switch (imageType) { default: case ImageType.PNG: outputFormat = FREE_IMAGE_FORMAT.FIF_PNG; break; case ImageType.WEBP: outputFormat = FREE_IMAGE_FORMAT.FIF_WEBP; if (lossless) { saveFlags = FREE_IMAGE_SAVE_FLAGS.WEBP_LOSSLESS; } else { saveFlags = (FREE_IMAGE_SAVE_FLAGS)90; } break; } //Kind of weird, ogre and freeimage are backwards from one another in terms of scanline 0 being the top or bottom //This easily fixes the math below by just flipping the image first. Note that pages must be flipped back over because //of this when they are saved. image.RotateFlip(RotateFlipType.RotateNoneFlipY); pagedImage.numImages = 0; pagedImage.imageType = (int)imageType; pagedImage.imageXSize = image.Width; pagedImage.imageYSize = image.Height; pagedImage.pageSize = pageSize; if (pagedImage.imageXSize != pagedImage.imageYSize) { throw new InvalidDataException("Image must be a square"); } int mipLevelCount = 0; int numPages = 0; for (int i = pagedImage.imageXSize; i >= pageSize; i >>= 1) { ++mipLevelCount; int pagesForMip = i / pageSize; numPages += pagesForMip * pagesForMip; } pagedImage.pages = new List <ImageInfo>(numPages); pagedImage.mipIndices = new List <MipIndexInfo>(mipLevelCount); IntSize2 fullPageSize = new IntSize2(pageSize + padding2x, pageSize + padding2x); for (int mip = 0; mip < mipLevelCount; ++mip) { //Setup mip level if (mip != 0) { pageSizeStrategy.rescaleImage(image, new Size(image.Width >> 1, image.Height >> 1), filter); if (afterResize != null) { //Flip so external functions aren't confused image.RotateFlip(RotateFlipType.RotateNoneFlipY); afterResize(image); //Flip back for correct math image.RotateFlip(RotateFlipType.RotateNoneFlipY); } } int size = image.Width / pageSize; pagedImage.mipIndices.Add(new MipIndexInfo(pagedImage.numImages, size)); pageSizeStrategy.extractPage(image, padding, stream, pagedImage, pageSize, fullPageSize, size, outputFormat, saveFlags); } //Write half size mip int halfPageSize = pageSize >> 1; IntSize2 halfSizePadded = new IntSize2(halfPageSize + padding2x, halfPageSize + padding2x); pageSizeStrategy.rescaleImage(image, new Size(image.Width >> 1, image.Height >> 1), filter); pageSizeStrategy.extractPage(image, padding, stream, pagedImage, halfPageSize, halfSizePadded, 1, outputFormat, saveFlags); pagedImage.indexStart = (int)stream.Position; using (BinaryWriter sw = new BinaryWriter(stream, EncodingShim.Default, true)) { foreach (var imageInfo in pagedImage.pages) { imageInfo.write(sw); } //Go back to header reserved space sw.BaseStream.Seek(0, SeekOrigin.Begin); sw.Write(MagicNumber); sw.Write(pagedImage.numImages); sw.Write(pagedImage.imageType); sw.Write(pagedImage.imageXSize); sw.Write(pagedImage.imageYSize); sw.Write(pagedImage.pageSize); sw.Write(pagedImage.indexStart); } }
public static extern FIBITMAP Rescale(FIBITMAP dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
public static FIBITMAP? ShrinkImageFI(FileInfo fileIn, FileInfo fileOut, Size nuSize, FREE_IMAGE_FORMAT saveFormat, FREE_IMAGE_FILTER filter, FREE_IMAGE_SAVE_FLAGS savequality, bool cleanup) { FIBITMAP? dib = GetJPGImageHandle(fileIn); if (dib != null) { FIBITMAP ddib = (FIBITMAP)dib; ShrinkImageFI(ddib, fileOut, nuSize, filter, savequality); if (cleanup) { CleanUpResources(ddib); } } return dib; }