Example #1
0
        public void StartLibrary(TexImage image)
        {
            if (Tools.IsCompressed(image.Format))
            {
                Log.Error("FreeImage can't process compressed texture.");
                throw new TextureToolsException("FreeImage can't process compressed texture.");
            }

            FreeImageTextureLibraryData libraryData = new FreeImageTextureLibraryData();

            image.LibraryData[this] = libraryData;

            libraryData.Bitmaps = new FIBITMAP[image.SubImageArray.Length];
            uint bpp = Tools.GetBPP(image.Format);

            for (int i = 0; i < image.SubImageArray.Length; ++i)
            {
                libraryData.Bitmaps[i] = FreeImage.ConvertFromRawBits(image.SubImageArray[i].Data, FREE_IMAGE_TYPE.FIT_BITMAP, image.SubImageArray[i].Width, image.SubImageArray[i].Height, image.SubImageArray[i].RowPitch, bpp, 0x00FF0000, 0x0000FF00, 0x000000FF, false);
            }

            if (image.DisposingLibrary != null)
            {
                image.DisposingLibrary.Dispose(image);
            }

            image.DisposingLibrary = this;

            libraryData.Data = IntPtr.Zero;
        }
Example #2
0
        public bool SaveDepthMap(string fileName)
        {
            FIBITMAP depthMap = FreeImage.ConvertFromRawBits(depthMapBytes, (int)width, (int)height, (int)stride, bpp * 8, redMask, greenMask, blueMask, false);
            bool     result   = FreeImage.SaveEx(depthMap, fileName);

            FreeImage.UnloadEx(ref depthMap);
            return(result);
        }
Example #3
0
        public bool SaveTexture(string fileName)
        {
            FIBITMAP texture = FreeImage.ConvertFromRawBits(textureBytes, (int)width, (int)height, (int)stride, bpp * 8, redMask, greenMask, blueMask, false);
            bool     result  = FreeImage.SaveEx(texture, fileName);

            FreeImage.UnloadEx(ref texture);
            return(result);
        }
        // Loading function
        protected override FIBITMAP LoadProc(ref FreeImageIO io, fi_handle handle, int page, int flags, IntPtr data)
        {
            // Check if the data has the correct format
            if (!ValidateProc(ref io, handle))
            {
                // Create a free-image message
                FreeImage.OutputMessageProc(format, "Invalid format.");
                // return 0 (operation failed)
                return(FIBITMAP.Zero);
            }

            SerialDib sdib;
            int       read = 0;

            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            byte[] buffer = new byte[1024];

            do
            {
                // Use the helper function 'Read' to read from the source
                read = Read(io, handle, 1, 1024, ref buffer);

                // Store the data in a temporary buffer
                stream.Write(buffer, 0, read);
            }while (read != 0);

            // Set the memory stream back to the beginning.
            stream.Position = 0;

            // Unzip the stream
            GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress);

            // Create a serializer
            BinaryFormatter formatter = new BinaryFormatter();

            // Deserialize the stream
            sdib = (SerialDib)formatter.Deserialize(zipStream);

            // Unload the stream
            zipStream.Dispose();

            // Use 'ConvertFromRawBits and the deserialized struct to recreate the bitmap
            // In this case the marshaller is used to create the needed IntPtr to the data
            // array.
            FIBITMAP dib = FreeImage.ConvertFromRawBits(
                Marshal.UnsafeAddrOfPinnedArrayElement(sdib.data, 0),
                (int)sdib.width, (int)sdib.height, sdib.pitch, sdib.bpp,
                sdib.red_mask, sdib.green_mask, sdib.blue_mask,
                false);

            // Unload the temporary stream
            stream.Dispose();

            // Return the created bitmap
            return(dib);
        }
Example #5
0
        public BitmapContent(int width, int height, ImageType imageType, byte[] data)
        {
            Width     = width;
            Height    = height;
            ImageType = imageType;
            int             bpp;
            FREE_IMAGE_TYPE type = ImageTypeToFreeImageType(imageType, out bpp);

            _bitmap = FreeImage.ConvertFromRawBits(data, type, width, height, width * bpp, (uint)bpp, 0, 0, 0, false);
        }
Example #6
0
        public void StartLibrary(TexImage image)
        {
            if (image.Format.IsCompressed())
            {
                Log.Error("FreeImage can't process compressed texture.");
                throw new TextureToolsException("FreeImage can't process compressed texture.");
            }

            var libraryData = new FreeImageTextureLibraryData();

            image.LibraryData[this] = libraryData;

            libraryData.Bitmaps = new FIBITMAP[image.SubImageArray.Length];

            FREE_IMAGE_TYPE type;
            uint            bpp, redMask, greenMask, blueMask;

            if (!FreeImage.GetFormatParameters(image.Format, out type, out bpp, out redMask, out greenMask, out blueMask))
            {
                throw new ArgumentException("The pixel format '{0}' is not supported by FreeImage".ToFormat(image.Format));
            }
            for (int i = 0; i < image.SubImageArray.Length; ++i)
            {
                var data   = image.SubImageArray[i].Data;
                var width  = image.SubImageArray[i].Width;
                var heigth = image.SubImageArray[i].Height;
                var pitch  = image.SubImageArray[i].RowPitch;
                libraryData.Bitmaps[i] = FreeImage.ConvertFromRawBits(data, type, width, heigth, pitch, bpp, redMask, greenMask, blueMask, false);
            }

            if (image.DisposingLibrary != null)
            {
                image.DisposingLibrary.Dispose(image);
            }

            image.DisposingLibrary = this;

            libraryData.Data = IntPtr.Zero;
        }
Example #7
0
        internal static BitmapContent Resize(this BitmapContent bitmap, int newWidth, int newHeight)
        {
            BitmapContent src = bitmap;
            SurfaceFormat format;

            src.TryGetFormat(out format);
            if (format != SurfaceFormat.Vector4)
            {
                var v4 = new PixelBitmapContent <Vector4>(src.Width, src.Height);
                BitmapContent.Copy(src, v4);
                src = v4;
            }

            // Convert to FreeImage bitmap
            var bytes = src.GetPixelData();
            var fi    = FreeImage.ConvertFromRawBits(bytes, FREE_IMAGE_TYPE.FIT_RGBAF, src.Width, src.Height, SurfaceFormat.Vector4.GetSize() * src.Width, 128, 0, 0, 0, true);

            // Resize
            var newfi = FreeImage.Rescale(fi, newWidth, newHeight, FREE_IMAGE_FILTER.FILTER_BICUBIC);

            FreeImage.UnloadEx(ref fi);

            // Convert back to PixelBitmapContent<Vector4>
            src   = new PixelBitmapContent <Vector4>(newWidth, newHeight);
            bytes = new byte[SurfaceFormat.Vector4.GetSize() * newWidth * newHeight];
            FreeImage.ConvertToRawBits(bytes, newfi, SurfaceFormat.Vector4.GetSize() * newWidth, 128, 0, 0, 0, true);
            src.SetPixelData(bytes);
            FreeImage.UnloadEx(ref newfi);
            // Convert back to source type if required
            if (format != SurfaceFormat.Vector4)
            {
                var s = (BitmapContent)Activator.CreateInstance(bitmap.GetType(), new object[] { newWidth, newHeight });
                BitmapContent.Copy(src, s);
                src = s;
            }

            return(src);
        }
Example #8
0
        public bool SaveNormalMap(string fileName)
        {
            // Insert the depth map on the alpha component, if selected
            if (DepthMapOnAlpha)
            {
                int row   = 0;
                int col   = 0;
                int index = 0;
                for (row = 0; row < height; row++)
                {
                    for (col = 0; col < width; col++)
                    {
                        index = row * (int)stride + col * (int)bpp;
                        normalMapBytes[index + 3] = depthMapBytes[index];
                    }
                }
            }

            FIBITMAP normalMap = FreeImage.ConvertFromRawBits(normalMapBytes, (int)width, (int)height, (int)stride, bpp * 8, redMask, greenMask, blueMask, false);
            bool     result    = FreeImage.SaveEx(normalMap, fileName);

            FreeImage.UnloadEx(ref normalMap);
            return(result);
        }
    private void SaveHelper(TextureFormat format, byte[] rawBytes, int texwidth, int texheight, bool convertTo16,
                            ChannelsPerMap exportChannels, string imagePath, FREE_IMAGE_FORMAT destFormat, FREE_IMAGE_SAVE_FLAGS saveFlags)
    {
        int             bytesPerPixel = 4;
        FREE_IMAGE_TYPE imageType     = FREE_IMAGE_TYPE.FIT_BITMAP;

        switch (format)
        {
        case TextureFormat.RGBAHalf:
            imageType     = FREE_IMAGE_TYPE.FIT_RGBA16;
            bytesPerPixel = 8;
            break;

        case TextureFormat.RGBAFloat:
            imageType     = FREE_IMAGE_TYPE.FIT_RGBAF;
            bytesPerPixel = 16;
            break;

        case TextureFormat.ARGB32:
            imageType     = FREE_IMAGE_TYPE.FIT_BITMAP;
            bytesPerPixel = 4;
            //tex.GetPixels32();
            //ConvertBGRAtoARGBScanline(dib);
            // convert back to ARGB
            if (FreeImage.IsLittleEndian())
            {
                for (int j = 0; j < rawBytes.Length; j += 4)
                {
                    // convert BGRA to ARGB
                    var a = rawBytes[j];
                    var r = rawBytes[j + 1];
                    rawBytes[j]     = rawBytes[j + 3];
                    rawBytes[j + 1] = rawBytes[j + 2];
                    rawBytes[j + 2] = r;
                    rawBytes[j + 3] = a;
                }
            }
            break;

        case TextureFormat.RGB24:
            imageType     = FREE_IMAGE_TYPE.FIT_BITMAP;
            bytesPerPixel = 3;
            if (FreeImage.IsLittleEndian())
            {
                // convert back to RGB
                for (int i = 0; i < rawBytes.Length; i += 3)
                {
                    // convert BGR to RGB
                    var r = rawBytes[i];
                    rawBytes[i]     = rawBytes[i + 2];
                    rawBytes[i + 2] = r;
                }
            }
            break;
        }



        FIBITMAP dib = FreeImage.ConvertFromRawBits(rawBytes, imageType, texwidth, texheight, texwidth * bytesPerPixel, (uint)bytesPerPixel * 8, 0, 0, 0, false);

        if (dib.IsNull)
        {
            Debug.LogError("Dib is NULL!!!");
        }
        rawBytes = null;
        GC.Collect();
        if (convertTo16)
        {
            dib    = FreeImage.ConvertToType(dib, FREE_IMAGE_TYPE.FIT_RGBA16, false);
            format = TextureFormat.RGBAHalf;
        }

        switch (exportChannels)
        {
        case ChannelsPerMap.RGB:
            // remove alpha channel
            switch (format)
            {
            case TextureFormat.RGBAFloat:
                dib = FreeImage.ConvertToRGBF(dib);
                break;

            case TextureFormat.RGBAHalf:
                dib = FreeImage.ConvertToType(dib, FREE_IMAGE_TYPE.FIT_RGB16, false);
                break;

            case TextureFormat.ARGB32:
                dib = FreeImage.ConvertTo24Bits(dib);
                break;
            }
            break;

        case ChannelsPerMap.R:
            dib = FreeImage.GetChannel(dib, FREE_IMAGE_COLOR_CHANNEL.FICC_RED);
            break;

        // if already RGBA don't need to do any conversion
        default:
            break;
        }

        try
        {
            using (FileStream saveStream = new FileStream(imagePath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                Debug.Log("FreeImage::FileSaveSuccess: " + imagePath + " :" + FreeImage.SaveToStream(ref dib, saveStream, destFormat, saveFlags, true));
            }
        }
        catch (Exception e)
        {
            Debug.LogException(e);
            //progressBar.DoneProgress();
            FreeImage.UnloadEx(ref dib);
            throw;
        }
        //if (progressBar != null)
        //{
        //    UnityThreadHelper.Dispatcher.Dispatch(() =>
        //    {
        //        progressBar.Increment();
        //    });
        //}
    }
Example #10
0
        public void Generate(out Bitmap normalMap, out Bitmap depthMap)
        {
            // Red and Blue components are swapped in little endian systems
            const int r = 2;
            const int g = 1;
            const int b = 0;
            const int a = 3;

            normalMap = null;
            depthMap  = null;

            if (bpp != 3 && bpp != 4)
            {
                return;
            }

            // Apply Grayscale
            float normalizedVal = 1.0f / 255.0f;
            float val           = 0.0f;
            int   index         = 0;

            int row = 0;
            int col = 0;

            for (row = 0; row < height; row++)
            {
                for (col = 0; col < width; col++)
                {
                    index = row * (int)stride + col * (int)bpp;
                    val   =
                        (((float)textureBytes[index + r]) * 0.3f +
                         ((float)textureBytes[index + g]) * 0.59f +
                         ((float)textureBytes[index + b]) * 0.11f) * normalizedVal;

                    edgePixels[row * width + col] = val;
                    textureBytes[index + a]       = 255;
                }
            }

            // Choose the currently selected filter
            FilterData[] filter = null;
            switch (Filter)
            {
            case EdgeFilter.Sobel3X3:
                filter = sobel3x3;
                break;

            case EdgeFilter.Sobel5X5:
                filter = sobel5x5;
                break;

            case EdgeFilter.Sobel7X7:
                filter = sobel7x7;
                break;

            case EdgeFilter.Sobel9X9:
                filter = sobel9x9;
                break;
            }

            // Apply edge filter
            float dx  = 0.0f;
            float dy  = 0.0f;
            byte  sum = 0;
            int   i   = 0;

            for (row = 0; row < height; row++)
            {
                for (col = 0; col < width; col++)
                {
                    if (WrapBorder)
                    {
                        for (i = 0; i < filter.Length; i++)
                        {
                            dx += GetEdgePixelWrap(row + filter[i].row, col + filter[i].col) * filter[i].wX;
                            dy += GetEdgePixelWrap(row + filter[i].row, col + filter[i].col) * filter[i].wY;
                        }
                    }
                    else
                    {
                        for (i = 0; i < filter.Length; i++)
                        {
                            dx += GetEdgePixel(row + filter[i].row, col + filter[i].col) * filter[i].wX;
                            dy += GetEdgePixel(row + filter[i].row, col + filter[i].col) * filter[i].wY;
                        }
                    }

                    // Apply the level of bumpiness on the derivatives
                    // The bigger the value, the bumpier the image will look
                    dx *= Strength;
                    dy *= Strength;

                    // Normalize it and get Z (which is the normal)
                    vec[0] = -dx;
                    vec[1] = -dy;
                    vec[2] = 1.0f;
                    NormalizeVector(ref vec);

                    // Invert values if requested
                    if (InvertX)
                    {
                        vec[0] = -vec[0];
                    }
                    if (InvertY)
                    {
                        vec[1] = -vec[1];
                    }

                    // Process the fast version of the Sobel algorithm for the depth map
                    sum = (byte)((dx * dx + dy * dy) * 255.0f);
                    if (sum > 255)
                    {
                        sum = 255;
                    }

                    // Now map from the [-1.0f, 1.0f] range to the [0, 255] range
                    index = row * (int)stride + col * (int)bpp;
                    normalMapBytes[index + r] = (byte)((vec[0] + 1.0f) * 127.5f);
                    normalMapBytes[index + g] = (byte)((vec[1] + 1.0f) * 127.5f);
                    normalMapBytes[index + b] = (byte)((vec[2] + 1.0f) * 127.5f);
                    normalMapBytes[index + a] = 255;

                    // Store edge values on the depth map byte array
                    depthMapBytes[index + r] = sum;
                    depthMapBytes[index + g] = sum;
                    depthMapBytes[index + b] = sum;
                    depthMapBytes[index + a] = 255;

                    dx  = 0.0f;
                    dy  = 0.0f;
                    sum = 0;
                }
            }

            // Convert the bits from IntPtr to bytes and create the images
            System.IntPtr bits          = Marshal.UnsafeAddrOfPinnedArrayElement(normalMapBytes, 0);
            FIBITMAP      normalMapScan = FreeImage.ConvertFromRawBits(bits, (int)width, (int)height, (int)stride, bpp * 8, redMask, greenMask, blueMask, false);

            normalMap = FreeImage.GetBitmap(normalMapScan);

            bits = Marshal.UnsafeAddrOfPinnedArrayElement(depthMapBytes, 0);
            FIBITMAP depthMapScan = FreeImage.ConvertFromRawBits(bits, (int)width, (int)height, (int)stride, bpp * 8, redMask, greenMask, blueMask, false);

            depthMap = FreeImage.GetBitmap(depthMapScan);
        }