/// <summary> /// Loads the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="libraryData">The library data.</param> /// <param name="loader">The loader.</param> /// <exception cref="TextureToolsException">If loading failed : mostly not supported format or path error (FileNotFound).</exception> private void Load(TexImage image, FreeImageTextureLibraryData libraryData, LoadingRequest loader) { Log.Verbose("Loading " + loader.FilePath + " ..."); FIBITMAP temp; FREE_IMAGE_FORMAT fileFormat = FREE_IMAGE_FORMAT.FIF_UNKNOWN; try { temp = FreeImage.LoadEx(loader.FilePath, ref fileFormat); FreeImage.FlipVertical(temp); if (temp.IsNull) { throw new Exception("FreeImage's image data is null"); } } catch (Exception e) { Log.Error("Loading file " + loader.FilePath + " failed: " + e.Message); throw new TextureToolsException("Loading file " + loader.FilePath + " failed: " + e.Message); } // Converting the image into BGRA_8888 format libraryData = new FreeImageTextureLibraryData { Bitmaps = new [] { FreeImage.ConvertTo32Bits(temp) } }; image.LibraryData[this] = libraryData; int alphaSize = GetAlphaDepth(fileFormat, temp); FreeImage.Unload(temp); image.Data = FreeImage.GetBits(libraryData.Bitmaps[0]); image.Width = (int)FreeImage.GetWidth(libraryData.Bitmaps[0]); image.Height = (int)FreeImage.GetHeight(libraryData.Bitmaps[0]); image.Depth = 1; image.Dimension = image.Height == 1 ? TexImage.TextureDimension.Texture1D : TexImage.TextureDimension.Texture2D; image.Format = loader.LoadAsSRgb? PixelFormat.B8G8R8A8_UNorm_SRgb : PixelFormat.B8G8R8A8_UNorm; image.OriginalAlphaDepth = alphaSize; int rowPitch, slicePitch; Tools.ComputePitch(image.Format, image.Width, image.Height, out rowPitch, out slicePitch); image.RowPitch = rowPitch; image.SlicePitch = slicePitch; //Only one image in the SubImageArray, FreeImage is only used to load images, not textures. image.SubImageArray[0].Data = image.Data; image.SubImageArray[0].DataSize = image.DataSize; image.SubImageArray[0].Width = image.Width; image.SubImageArray[0].Height = image.Height; image.SubImageArray[0].RowPitch = rowPitch; image.SubImageArray[0].SlicePitch = slicePitch; image.DataSize = (int)(FreeImage.GetDIBSize(libraryData.Bitmaps[0]) - GetHeaderSize()); // header size of a bitmap is included in their size calculus libraryData.Data = IntPtr.Zero; image.DisposingLibrary = this; }
/// <summary> /// Called by the XNA Framework when importing a texture file to be used as a game asset. This is the method called by the XNA Framework when an asset is to be imported into an object that can be recognized by the Content Pipeline. /// </summary> /// <param name="filename">Name of a game asset file.</param> /// <param name="context">Contains information for importing a game asset, such as a logger interface.</param> /// <returns>Resulting game asset.</returns> public override TextureContent Import(string filename, ContentImporterContext context) { var output = new Texture2DContent { Identity = new ContentIdentity(filename) }; #if WINDOWS || MACOS // TODO: This is a pretty lame way to do this. It would be better // if we could completely get rid of the System.Drawing.Bitmap // class and replace it with FreeImage, but some other processors/importers // such as Font rely on Bitmap. Soon, we should completely remove any references // to System.Drawing.Bitmap and replace it with FreeImage. For now // this is the quickest way to add support for virtually every input Texture // format without breaking functionality in other places. var fBitmap = FreeImage.LoadEx(filename); var info = FreeImage.GetInfoHeaderEx(fBitmap); // creating a System.Drawing.Bitmap from a >= 64bpp image isn't // supported. if (info.biBitCount > 32) { var temp = FreeImage.ConvertTo32Bits(fBitmap); // The docs are unclear on what's happening here... // If a new bitmap is created or if the old is just converted. // UnloadEx doesn't throw any exceptions if it's called multiple // times on the same bitmap, so just being cautious here. FreeImage.UnloadEx(ref fBitmap); fBitmap = temp; } var systemBitmap = FreeImage.GetBitmap(fBitmap); FreeImage.UnloadEx(ref fBitmap); #else var systemBitmap = new Bitmap(filename); #endif var height = systemBitmap.Height; var width = systemBitmap.Width; // Force the input's pixelformat to ARGB32, so we can have a common pixel format to deal with. if (systemBitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Format32bppArgb) { var bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); using (var graphics = System.Drawing.Graphics.FromImage(bitmap)) { graphics.DrawImage(systemBitmap, 0, 0, width, height); } systemBitmap = bitmap; } output.Faces[0].Add(systemBitmap.ToXnaBitmap(true)); systemBitmap.Dispose(); return(output); }
private void btnLoadFile_Click(object sender, EventArgs e) { // Loads up a file dialog OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "Image Files|*.bmp;*.jpg;*.png;*.gif;*.tga; | All files|*.*"; if (ofd.ShowDialog() == DialogResult.OK) { // If there were previous textures, dispose of them ClearTextures(); // Load a temporary file FIBITMAP tmpFile = FreeImage.LoadEx(ofd.FileName); if (tmpFile.IsNull) { MessageBox.Show("Couldn't load the selected image!"); return; } // Convert it to 32 bits FIBITMAP imgFile = FreeImage.ConvertTo32Bits(tmpFile); // Dispose of the temp file FreeImage.UnloadEx(ref tmpFile); // Get a .NET bitmap from FreeImage bmTexture = FreeImage.GetBitmap(imgFile); // Get the bytes as well as other information from the file normalMap.SetTexture(imgFile); // Dispose of another FreeImage file FreeImage.UnloadEx(ref imgFile); // Put it on screen pbxTexture.Image = bmTexture; // Generate the normal map with the default settings GenerateNormalMap(); // Enable the options ToggleOptions(true); } }
/// <summary> /// Uploads an array of bytes as a texture. /// </summary> /// <param name="data">The bytes to upload.</param> internal override void Create(byte[] data) { FIBITMAP freeImageBitmap; // Put the bytes into a stream. using (MemoryStream stream = new MemoryStream(data)) { // Get the image format and load the image as a FreeImageBitmap. FREE_IMAGE_FORMAT fileType = FreeImage.GetFileTypeFromStream(stream); freeImageBitmap = FreeImage.ConvertTo32Bits(FreeImage.LoadFromStream(stream, ref fileType)); // Assign size. Size = new Vector2(FreeImage.GetWidth(freeImageBitmap), FreeImage.GetHeight(freeImageBitmap)); } // Upload the texture on the GL thread. GLThread.ExecuteGLThread(() => { Pointer = GL.GenTexture(); TextureMatrix = Matrix4.CreateOrthographicOffCenter(0, Size.X * 2, Size.Y * 2, 0, 0, 1); // Bind the texture. Bind(0); // Set scaling to pixel perfect. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)All.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)All.Nearest); // Create a swizzle mask to convert RGBA to BGRA which for some reason is the format FreeImage spits out above. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, (int)All.Blue); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, (int)All.Green); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, (int)All.Red); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, (int)All.Alpha); // Upload the texture. GL.TexImage2D(TextureTarget2d.Texture2D, 0, TextureComponentCount.Rgba8, (int)Size.X, (int)Size.Y, 0, PixelFormat.Rgba, PixelType.UnsignedByte, FreeImage.GetBits(freeImageBitmap)); Helpers.CheckError("uploading texture"); // Cleanup FreeImage object. FreeImage.Unload(freeImageBitmap); }); }
/// <summary> /// Expands images to have an alpha channel and swaps red and blue channels /// </summary> /// <param name="fBitmap">Image to process</param> /// <param name="imageType">Type of the image for the procedure</param> /// <returns></returns> private static FIBITMAP ConvertAndSwapChannels(FIBITMAP fBitmap, FREE_IMAGE_TYPE imageType) { FIBITMAP bgra; switch (imageType) { // Return BGRA images as is case FREE_IMAGE_TYPE.FIT_RGBAF: case FREE_IMAGE_TYPE.FIT_RGBA16: break; // Add an alpha channel to BGRA images without one case FREE_IMAGE_TYPE.FIT_RGBF: bgra = FreeImage.ConvertToType(fBitmap, FREE_IMAGE_TYPE.FIT_RGBAF, true); FreeImage.UnloadEx(ref fBitmap); fBitmap = bgra; break; case FREE_IMAGE_TYPE.FIT_RGB16: bgra = FreeImage.ConvertToType(fBitmap, FREE_IMAGE_TYPE.FIT_RGBA16, true); FreeImage.UnloadEx(ref fBitmap); fBitmap = bgra; break; // Add an alpha channel to RGB images // Swap the red and blue channels of RGBA images default: // Bitmap and other formats are converted to 32-bit by default bgra = FreeImage.ConvertTo32Bits(fBitmap); SwitchRedAndBlueChannels(bgra); FreeImage.UnloadEx(ref fBitmap); fBitmap = bgra; break; } return(fBitmap); }
/// <summary> /// Load the texture from source /// </summary> /// <param name="source"></param> public override bool Load(string source) { if (source.Contains(".casset")) { return(InternalLoad(source)); } this.Source = source; Target = TextureTarget.Texture2D; Unit = TextureUnit.Texture0; _id = (uint)GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, (int)_id); GL.TexParameter(Target, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(Target, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); format = FreeImage.GetFileType(source, 0); FIBITMAP temp = FreeImage.Load(format, source, FREE_IMAGE_LOAD_FLAGS.DEFAULT); bitmap = FreeImage.ConvertTo32Bits(temp); FreeImage.Unload(temp); _width = FreeImage.GetWidth(bitmap); _height = FreeImage.GetHeight(bitmap); pixels = FreeImage.GetBits(bitmap); GL.TexImage2D(Target, 0, PixelInternalFormat.Rgba, (int)_width, (int)_height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, pixels); GL.TexParameter(Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear); GL.TexParameter(Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.GenerateTextureMipmap(_id); _bpp = FreeImage.GetBPP(bitmap); return(true); }
/// <summary> /// Expands images to have an alpha channel and swaps red and blue channels /// </summary> /// <param name="fBitmap">Image to process</param> /// <param name="imageType">Type of the image for the procedure</param> /// <returns></returns> private static FIBITMAP ConvertAndSwapChannels(FIBITMAP fBitmap, FREE_IMAGE_TYPE imageType) { FIBITMAP bgra; switch (imageType) { // RGBF are switched before adding an alpha channel. case FREE_IMAGE_TYPE.FIT_RGBF: // Swap R and B channels to make it BGR, then add an alpha channel SwitchRedAndBlueChannels(fBitmap); bgra = FreeImage.ConvertToType(fBitmap, FREE_IMAGE_TYPE.FIT_RGBAF, true); FreeImage.UnloadEx(ref fBitmap); fBitmap = bgra; break; case FREE_IMAGE_TYPE.FIT_RGB16: // Swap R and B channels to make it BGR, then add an alpha channel SwitchRedAndBlueChannels(fBitmap); bgra = FreeImage.ConvertToType(fBitmap, FREE_IMAGE_TYPE.FIT_RGBA16, true); FreeImage.UnloadEx(ref fBitmap); fBitmap = bgra; break; case FREE_IMAGE_TYPE.FIT_RGBAF: case FREE_IMAGE_TYPE.FIT_RGBA16: // Swap R and B channels to make it BGRA SwitchRedAndBlueChannels(fBitmap); break; default: // Bitmap and other formats are converted to 32-bit by default bgra = FreeImage.ConvertTo32Bits(fBitmap); SwitchRedAndBlueChannels(bgra); FreeImage.UnloadEx(ref fBitmap); fBitmap = bgra; break; } return(fBitmap); }
protected override void CreateInternal(byte[] data) { // Create a GL pointer to the new texture. Pointer = Engine.GraphicsManager.CreateTexture(); FIBITMAP freeImageBitmap; // Put the bytes into a stream. using (MemoryStream stream = new MemoryStream(data)) { // Get the image format and load the image as a FreeImageBitmap. FREE_IMAGE_FORMAT fileType = FreeImage.GetFileTypeFromStream(stream); freeImageBitmap = FreeImage.ConvertTo32Bits(FreeImage.LoadFromStream(stream, ref fileType)); // Assign size. Size = new Vector2(FreeImage.GetWidth(freeImageBitmap), FreeImage.GetHeight(freeImageBitmap)); } FIBITMAP preRotation = freeImageBitmap; freeImageBitmap = FreeImage.Rotate(preRotation, 180); FreeImage.Unload(preRotation); TextureMatrix = Matrix4x4.CreateOrthographicOffCenter(0, Size.X * 2, Size.Y * 2, 0, 0, 1) * Matrix4x4.CreateScale(-1, -1, 1); // Even though all of the calls in the graphics manager call for execution on the GL Thread, wrapping them together like this ensures they'll be called within one loop. GLThread.ExecuteGLThread(() => { Engine.GraphicsManager.BindTexture(Pointer); Engine.GraphicsManager.SetTextureMask(0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff); Engine.GraphicsManager.UploadToTexture(FreeImage.GetBits(freeImageBitmap), Size, TextureInternalFormat.Rgba8, TexturePixelFormat.Rgba); }); // Cleanup FreeImage object. FreeImage.Unload(freeImageBitmap); }
public RenderTexture LoadImage(string path, bool isLinear = false, bool isGrayscale = false, bool doMipMaps = false, bool forceGC = false, bool premultiplyAlpha = false) { // default bits per channel //uint origBPP = outBPP = 0; bool successfullyLoadedRaw = false; int width = 0, height = 0; TextureFormat formatToLoad = TextureFormat.ARGB32; RenderTextureFormat rtFormat = RenderTextureFormat.ARGB32; bool forceGrayscaleAfterTexture2D = false; //System.Threading.Thread newThread = new System.Threading.Thread(() => { var loadType = System.IO.Path.GetExtension(path); FREE_IMAGE_LOAD_FLAGS loadFlags = FREE_IMAGE_LOAD_FLAGS.DEFAULT; switch (loadType) { case ".png": loadFlags = FREE_IMAGE_LOAD_FLAGS.PNG_IGNOREGAMMA; break; case ".jpg": case ".jpeg": loadFlags = FREE_IMAGE_LOAD_FLAGS.JPEG_ACCURATE; break; } // Format is stored in 'format' on successfull load. FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; FIBITMAP dib; bool isModifiedEXR = false; char yChar = 'Y'; byte yByte = Convert.ToByte(yChar); char rChar = 'R'; byte rByte = Convert.ToByte(rChar); //byte[] byteArray = File.ReadAllBytes(path); FileStream stream = null; if (Path.GetExtension(path).ToLower() == ".exr") { stream = new FileStream(path, FileMode.Open); stream.Position = 66; isModifiedEXR = (stream.ReadByte() == rByte); if (isModifiedEXR) { Debug.Log("<color=blue>*** This is a modified EXR </color>"); //byteArray[66] = yByte; stream.Position = 66; stream.WriteByte(yByte); stream.Position = 0; } } #if UNITY_STANDALONE_OSX if (stream == null) { stream = new FileStream(path, FileMode.Open); } dib = FreeImage.LoadFromStream(stream, loadFlags, ref format); #else dib = FreeImage.LoadEx(path, loadFlags, ref format); Debug.Log("Used Heap Size After FreeImage.LoadEx: " + Profiler.GetMonoUsedSizeLong() / 1024 / 1024); #endif if (stream != null) { stream.Dispose(); GC.Collect(); Debug.Log("Used Heap Size After stream.Dispose: " + Profiler.GetMonoUsedSizeLong() / 1024 / 1024); } if (isModifiedEXR) { using (FileStream fs = new FileStream(path, FileMode.Open)) { fs.Position = 66; fs.WriteByte(rByte); fs.Position = 0; } } rtFormat = RenderTextureFormat.ARGB32; try { // Error handling if (dib.IsNull) { return(null); } FREE_IMAGE_TYPE origInputType = FreeImage.GetImageType(dib); //Debug.Log("DIB for :" + path); // read bits per channel of loaded image uint origBPP = FreeImage.GetBPP(dib); var header = FreeImage.GetInfoHeaderEx(dib); //Debug.Log("original BPP:" + origBPP); //Debug.Log("origInputType:" + origInputType); // check here if we need to convert single channel textures to RGB or vice versa based on source input texture type and destination type expected FREE_IMAGE_TYPE destType = FREE_IMAGE_TYPE.FIT_UNKNOWN; switch (origInputType) { case FREE_IMAGE_TYPE.FIT_UINT16: if (!isGrayscale) { destType = FREE_IMAGE_TYPE.FIT_RGBAF; } else { destType = FREE_IMAGE_TYPE.FIT_FLOAT; } break; case FREE_IMAGE_TYPE.FIT_RGBF: case FREE_IMAGE_TYPE.FIT_RGBAF: destType = isGrayscale ? FREE_IMAGE_TYPE.FIT_FLOAT : FREE_IMAGE_TYPE.FIT_RGBAF; break; case FREE_IMAGE_TYPE.FIT_RGB16: case FREE_IMAGE_TYPE.FIT_RGBA16: destType = isGrayscale ? FREE_IMAGE_TYPE.FIT_FLOAT : FREE_IMAGE_TYPE.FIT_RGBAF; break; case FREE_IMAGE_TYPE.FIT_BITMAP: if (isGrayscale) { if (Mathf.IsPowerOfTwo(header.biWidth) && Mathf.IsPowerOfTwo(header.biHeight)) { if (!premultiplyAlpha) { dib = FreeImage.ConvertToGreyscale(dib); } } else { //int w = Mathf.NextPowerOfTwo(header.biWidth); //int h = Mathf.NextPowerOfTwo(header.biHeight); //FIBITMAP bitmap2 = FreeImage.Allocate(w, h, 8); //FreeImage.Paste(bitmap2, dib, 0, 0, 255); //FreeImage.UnloadEx(ref dib); //dib = bitmap2; forceGrayscaleAfterTexture2D = true; dib = FreeImage.ConvertTo32Bits(dib); } } else { dib = FreeImage.ConvertTo32Bits(dib); } destType = FREE_IMAGE_TYPE.FIT_BITMAP; break; } //// premultiply if need be //if (premultiplyAlpha) // FreeImage.PreMultiplyWithAlpha(dib); // convert to destination expected type if (destType != FREE_IMAGE_TYPE.FIT_UNKNOWN && origInputType != destType) { Debug.Log("Trying to convert from:" + origInputType + ", to:" + destType); dib = FreeImage.ConvertToType(dib, destType, false); } //GC.Collect(); Debug.Log("Used Heap Size After FreeImage.ConvertToType: " + Profiler.GetMonoUsedSizeLong() / 1024 / 1024); //if (isModifiedEXR && origInputType == FREE_IMAGE_TYPE.FIT_FLOAT) width = (int)FreeImageAPI.FreeImage.GetWidth(dib); height = (int)FreeImageAPI.FreeImage.GetHeight(dib); uint bpp = FreeImage.GetBPP(dib); int pitch = (int)FreeImage.GetPitch(dib); long byteSize = pitch * height; Debug.Log("byteSize: " + byteSize); FREE_IMAGE_TYPE inputType = FreeImage.GetImageType(dib); if (doMipMaps) { byteSize = (long)(byteSize * 1.6666f); } //bytes = new byte[byteSize]; FreeImage.ConvertToRawBits(bytes, dib, pitch, bpp, 0, 0, 0, false); Debug.Log("Used Heap Size After FreeImage.ConvertToRawBits: " + Profiler.GetMonoUsedSizeLong() / 1024 / 1024); FreeImage.UnloadEx(ref dib); //GC.Collect(); //Debug.Log("Used Heap Size After FreeImage.UnloadEx: " + Profiler.GetMonoUsedSizeLong() / 1024 / 1024); // choose texture format formatToLoad = TextureFormat.ARGB32; Debug.Log("inputType:" + inputType); switch (inputType) { case FREE_IMAGE_TYPE.FIT_FLOAT: formatToLoad = TextureFormat.RFloat; if (origInputType == FREE_IMAGE_TYPE.FIT_UINT16) { rtFormat = RenderTextureFormat.RHalf; } else { rtFormat = RenderTextureFormat.RFloat; } break; case FREE_IMAGE_TYPE.FIT_UINT16: formatToLoad = TextureFormat.RHalf; rtFormat = RenderTextureFormat.RHalf; break; case FREE_IMAGE_TYPE.FIT_RGBA16: formatToLoad = TextureFormat.RGBAHalf; rtFormat = RenderTextureFormat.ARGBHalf; isLinear = true; break; case FREE_IMAGE_TYPE.FIT_RGBAF: formatToLoad = TextureFormat.RGBAFloat; if (origInputType == FREE_IMAGE_TYPE.FIT_RGBA16 || origInputType == FREE_IMAGE_TYPE.FIT_RGB16) { rtFormat = RenderTextureFormat.ARGBHalf; } else { rtFormat = RenderTextureFormat.ARGBFloat; } isLinear = true; break; case FREE_IMAGE_TYPE.FIT_BITMAP: //Iterate over all scanlines switch (bpp) { case 8: { formatToLoad = TextureFormat.Alpha8; rtFormat = RenderTextureFormat.R8; } break; case 16: formatToLoad = TextureFormat.RGBA4444; rtFormat = RenderTextureFormat.ARGB4444; break; case 24: if (FreeImage.IsLittleEndian()) { int length = bytes.Length; // make sure it's a multiple of 3 int factor = length / 3; int adjustedLength = factor * 3; // convert back to RGB for (int i = 0; i < adjustedLength; i += 3) { // convert BGR to RGB var r = bytes[i]; bytes[i] = bytes[i + 2]; bytes[i + 2] = r; } } formatToLoad = TextureFormat.RGB24; rtFormat = RenderTextureFormat.ARGB32; break; case 32: if (forceGrayscaleAfterTexture2D) { formatToLoad = TextureFormat.ARGB32; rtFormat = RenderTextureFormat.R8; } else { if (FreeImage.IsLittleEndian()) { int length = bytes.Length; // make sure it's a multiple of 4 int factor = length / 4; int adjustedLength = factor * 4; for (int j = 0; j < adjustedLength; j += 4) { // convert BGRA to ARGB var a = bytes[j]; var r = bytes[j + 1]; bytes[j] = bytes[j + 3]; bytes[j + 1] = bytes[j + 2]; bytes[j + 2] = r; bytes[j + 3] = a; } } formatToLoad = TextureFormat.ARGB32; rtFormat = RenderTextureFormat.ARGB32; } break; } break; } successfullyLoadedRaw = true; } catch (System.Exception ex) { Debug.LogError("Exception: " + ex.Message); } } //); //newThread.IsBackground = true; //newThread.Start(); //newThread.Join(); //outBPP = origBPP; if (successfullyLoadedRaw) { RenderTexture temp = LoadRawToTexture2D(bytes, width, height, formatToLoad, rtFormat, doMipMaps, isLinear, forceGC, premultiplyAlpha); //GC.Collect(); Debug.Log("Used Heap Size After LoadRawToTexture2D: " + Profiler.GetMonoUsedSizeLong() / 1024 / 1024); return(temp); } return(null); }
private ImageType ImageTypeFromBitmap(ref FIBITMAP bitmap) { // returns the ImageType for the given bitmap, also converts the bitmap to a 24 or 32 bit image if it is pallatized. FREE_IMAGE_TYPE type = FreeImage.GetImageType(bitmap); uint bpp = FreeImage.GetBPP(bitmap); FIBITMAP tmp; ImageType imageType = ImageType.RGBA; if (type == FREE_IMAGE_TYPE.FIT_RGBF) { return(ImageType.RGBf); } else if (type == FREE_IMAGE_TYPE.FIT_RGBAF) { return(ImageType.RGBAf); } else if (type == FREE_IMAGE_TYPE.FIT_BITMAP) { if (bpp == 8 && FreeImage.GetTransparencyCount(bitmap) > 0) { tmp = bitmap; bitmap = FreeImage.ConvertTo32Bits(tmp); FreeImage.Unload(tmp); imageType = ImageType.RGBA; } else if (bpp == 8) { tmp = bitmap; bitmap = FreeImage.ConvertTo24Bits(tmp); FreeImage.Unload(tmp); imageType = ImageType.RGB; } else if (bpp == 24) { imageType = ImageType.RGB; } else if (bpp == 32) { imageType = ImageType.RGBA; } else { // if its another type convert it to a 24 bit image tmp = bitmap; bitmap = FreeImage.ConvertTo24Bits(tmp); FreeImage.Unload(tmp); imageType = ImageType.RGB; } } else { throw new InvalidOperationException(string.Format("Unable to handle FREE_IMAGE_TYPE: {0}", type)); } if (IsLinear) { if (imageType == ImageType.RGB) { imageType = ImageType.sRGB8; } else if (imageType == ImageType.RGBA) { imageType = ImageType.sRGBA8; } } return(imageType); }
public static unsafe Texture Create(string filename) { filename = Utils.GetDataFilePath(filename); Console.WriteLine("Loading texture " + filename); //image format FREE_IMAGE_FORMAT fif = FREE_IMAGE_FORMAT.FIF_UNKNOWN; //pointer to the image, once loaded FIBITMAP dib = FIBITMAP.Zero; //pointer to the image data IntPtr bits = IntPtr.Zero; //image width and height int width = 0; int height = 0; //OpenGL's image ID to map to uint gl_texID; //check the file signature and deduce its format fif = FreeImage.GetFileType(filename, 0); //if still unknown, try to guess the file format from the file extension if (fif == FREE_IMAGE_FORMAT.FIF_UNKNOWN) { fif = FreeImage.GetFIFFromFilename(filename); } //if still unkown, return failure if (fif == FREE_IMAGE_FORMAT.FIF_UNKNOWN) { return(null); } //check that the plugin has reading capabilities and load the file if (FreeImage.FIFSupportsReading(fif)) { dib = FreeImage.Load(fif, filename, FREE_IMAGE_LOAD_FLAGS.DEFAULT); } //if the image failed to load, return failure if (dib == FIBITMAP.Zero) { return(null); } dib = FreeImage.ConvertTo32Bits(dib); //retrieve the image data bits = FreeImage.GetBits(dib); //get the image width and height width = (int)FreeImage.GetWidth(dib); height = (int)FreeImage.GetHeight(dib); //if this somehow one of these failed (they shouldn't), return failure if ((bits == IntPtr.Zero) || (width == 0) || (height == 0)) { return(null); } int pixelCount = width * height; byte *p = (byte *)bits; byte t = 0; for (int i = 0; i < pixelCount; i++) { int k = i * 4; t = p[k + 0]; p[k + 0] = p[k + 2]; p[k + 2] = t; } //int bytesize = pixelCount * 4; //byte[] test = new byte[bytesize]; //for(int i = 0; i < bytesize; i++) //{ // test[i] = p[i]; //} //generate an OpenGL texture ID for this texture Gl.glGenTextures(1, &gl_texID); Gl.glBindTexture(Gl.GL_TEXTURE_2D, gl_texID); //store the texture data for OpenGL use //uint bpp = FreeImage.GetBPP(dib); Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, width, height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, bits); Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR); Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR); //Free FreeImage's copy of the data FreeImage.Unload(dib); var err = Gl.GetError(); Console.WriteLine("[Texture:Create] " + err); return(new Texture { textureID = gl_texID }); }
protected override void OnLoad() { if (RawPixels == PixelBuffer.Empty) { base.OnLoad(); // Prepare unamanged pointer IntPtr Data = Marshal.AllocHGlobal(Content.Length); Marshal.Copy(Content, 0, Data, Content.Length); // Load memory FIMEMORY Memory = FreeImage.OpenMemory(Data, Size); // Get image format Format = FreeImage.GetFileTypeFromMemory(Memory, 0); // Get bitmap FIBITMAP Bitmap = FreeImage.LoadFromMemory(Format, Memory, FREE_IMAGE_LOAD_FLAGS.DEFAULT); // Get depth uint Depth = FreeImage.GetBPP(Bitmap) / 8; FIBITMAP ConvertedBirmap; // Convert to depth 4 if (Depth == 4) { ConvertedBirmap = Bitmap; } else { ConvertedBirmap = FreeImage.ConvertTo32Bits(Bitmap); FreeImage.Unload(Bitmap); } // Get meta Vector2i S = new Vector2i(); S.Width = (int)FreeImage.GetWidth(ConvertedBirmap); S.Height = (int)FreeImage.GetHeight(ConvertedBirmap); RawPixels = new PixelBuffer(S); // Get pixels IntPtr Pixels = FreeImage.GetBits(ConvertedBirmap); Marshal.Copy(Pixels, RawPixels.Pixels, 0, RawPixels.Pixels.Length); FreeImage.Unload(ConvertedBirmap); byte Swap; // Convert from GBRA to RGBA for (int i = 0; i < RawPixels.Pixels.Length; i += 4) { Swap = RawPixels.Pixels[i]; RawPixels.Pixels[i] = RawPixels.Pixels[i + 2]; RawPixels.Pixels[i + 2] = Swap; } // Free data Marshal.FreeHGlobal(Data); } }
private void LoadImage() { try { if (!System.IO.File.Exists(FFilename)) { throw (new Exception("Given filename '" + FFilename + "' is not a file")); } FREE_IMAGE_FORMAT format = FreeImage.GetFileType(FFilename, 0); FIBITMAP bmp = FreeImage.Load(format, FFilename, FREE_IMAGE_LOAD_FLAGS.JPEG_ACCURATE); if (bmp.IsNull == true) { throw (new Exception("Couldn't load file")); } if (FreeImage.GetColorType(bmp) == FREE_IMAGE_COLOR_TYPE.FIC_PALETTE || FreeImage.GetBPP(bmp) < 8) { FIBITMAP converted; //we need some conversion from strange pallettes if (FreeImage.IsTransparent(bmp)) { converted = FreeImage.ConvertTo32Bits(bmp); } else if (FreeImage.IsGreyscaleImage(bmp)) { converted = FreeImage.ConvertTo8Bits(bmp); } else { converted = FreeImage.ConvertTo24Bits(bmp); } FreeImage.Unload(bmp); bmp = converted; } //now we should have a fairly sensible 8, 24 or 32bit (uchar) image //or a float / hdr image uint width = FreeImage.GetWidth(bmp); uint height = FreeImage.GetHeight(bmp); uint bpp = FreeImage.GetBPP(bmp); FREE_IMAGE_TYPE type = FreeImage.GetImageType(bmp); TColorFormat CVFormat; if (type == FREE_IMAGE_TYPE.FIT_BITMAP) { //standard image (8bbp) uint channels = bpp / 8; switch (channels) { case (1): CVFormat = TColorFormat.L8; break; case (3): CVFormat = TColorFormat.RGB8; break; case (4): CVFormat = TColorFormat.RGBA8; break; default: CVFormat = TColorFormat.UnInitialised; break; } } else { switch (type) { case (FREE_IMAGE_TYPE.FIT_INT16): CVFormat = TColorFormat.L16; break; case (FREE_IMAGE_TYPE.FIT_FLOAT): CVFormat = TColorFormat.L32F; break; case (FREE_IMAGE_TYPE.FIT_INT32): CVFormat = TColorFormat.L32S; break; case (FREE_IMAGE_TYPE.FIT_RGBF): CVFormat = TColorFormat.RGB32F; break; case (FREE_IMAGE_TYPE.FIT_RGBAF): CVFormat = TColorFormat.RGBA32F; break; default: CVFormat = TColorFormat.UnInitialised; break; } } if (CVFormat == TColorFormat.UnInitialised) { FreeImage.Unload(bmp); throw (new Exception("VVVV.Nodes.OpenCV doesn't support this colour type \"" + type.ToString() + "\" yet. Please ask!")); } IntPtr data = FreeImage.GetBits(bmp); FOutput.Image.Initialise(new Size((int)width, (int)height), CVFormat); FOutput.Image.SetPixels(data); ImageUtils.FlipImageVertical(FOutput.Image); FOutput.Send(); FreeImage.Unload(bmp); Status = "OK"; } catch (Exception e) { Status = e.Message; } }