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();
        //    });
        //}
    }
            //---------------------------------------------------------------------------------------------------------
            /// <summary>
            /// Загрузка изображения по полному пути
            /// </summary>
            /// <param name="file_name">Имя файла</param>
            //---------------------------------------------------------------------------------------------------------
            public void Load(String file_name)
            {
                if (!mFreeImageBitmap.IsNull)
                {
                    mFreeImageBitmap.SetNull();
                }

                // Try loading the file
                mFreeImageFormat = FREE_IMAGE_FORMAT.FIF_UNKNOWN;
                mFreeImageBitmap = FreeImage.LoadEx(file_name, ref mFreeImageFormat);

                try
                {
                    // Error handling
                    if (mFreeImageBitmap.IsNull)
                    {
                        // Chech whether FreeImage generated an error messe
                        if (mCurrentMessage != null)
                        {
                            XLogger.LogErrorFormatModule(MODULE_NAME, "File could not be loaded!\nError:{0}", mCurrentMessage);
                        }
                        else
                        {
                            XLogger.LogErrorModule(MODULE_NAME, "File could not be loaded!");
                        }
                        return;
                    }


                    mFileName = file_name;

                    //
                    // РАЗМЕР ИЗОБРАЖЕНИЯ
                    //

                    // Read width
                    textWidth.Text = String.Format("Width: {0}", FreeImage.GetWidth(mFreeImageBitmap));

                    // Read height
                    textHeight.Text = String.Format("Height: {0}", FreeImage.GetHeight(mFreeImageBitmap));

                    // Read x-axis dpi
                    textDPI.Text = String.Format("DPI: x={0}, y={1}", FreeImage.GetResolutionX(mFreeImageBitmap),
                                                 FreeImage.GetResolutionY(mFreeImageBitmap));

                    //
                    // ПАРАМЕТРЫ ИЗОБРАЖЕНИЯ
                    //

                    // Read file format
                    textFileFormat.Text = String.Format("File Format: {0}", mFreeImageFormat);

                    // Read image type (FI_BITMAP, FIT_RGB16, FIT_COMPLEX ect)
                    textImageType.Text = String.Format("Image Type: {0}", FreeImage.GetImageType(mFreeImageBitmap));

                    // Read color type
                    textColorType.Text = String.Format("Color Depth: {0}", FreeImage.GetColorType(mFreeImageBitmap));

                    //
                    // ПАРАМЕТРЫ ЦВЕТА
                    //

                    // Read file format
                    textColorDepth.Text = String.Format("ColorDepth: {0}", FreeImage.GetBPP(mFreeImageBitmap));

                    // Read file format
                    textPixelFormat.Text = String.Format("PixelFormat: {0}", FreeImage.GetPixelFormat(mFreeImageBitmap));

                    // Read file format
                    textIsTransparent.Text = String.Format("IsTransparent: {0}", FreeImage.IsTransparent(mFreeImageBitmap));

                    //
                    // ПАРАМЕТРЫ МАСКИ
                    //

                    // Read red bitmask (16 - 32 bpp)
                    textRedMask.Text = String.Format("Red Mask: 0x{0:X8}", FreeImage.GetRedMask(mFreeImageBitmap));

                    // Read green bitmask (16 - 32 bpp)
                    textBlueMask.Text = String.Format("Green Mask: 0x{0:X8}", FreeImage.GetGreenMask(mFreeImageBitmap));

                    // Read blue bitmask (16 - 32 bpp)
                    textGreenMask.Text = String.Format("Blue Mask: 0x{0:X8}", FreeImage.GetBlueMask(mFreeImageBitmap));

                    // Получаем презентатор
                    if (mImagePresentator == null)
                    {
                        mImagePresentator = contentViewer.Content as Image;
                    }

                    // Основной режим
                    //mBitmapOriginal = FreeImage.GetBitmap(mFreeImageBitmap).ToBitmapSource();
                    mBitmapOriginal = null;                     // CreateFromHBitmap(FreeImage.GetHbitmap(mFreeImageBitmap, IntPtr.Zero, false));

                    // Если есть прозрачность
                    if (FreeImage.IsTransparent(mFreeImageBitmap) && FreeImage.GetBPP(mFreeImageBitmap) > 24)
                    {
                        // Получаем альфа-канал
                        FIBITMAP bitmap_alpha = FreeImage.GetChannel(mFreeImageBitmap, FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA);
                        if (!bitmap_alpha.IsNull)
                        {
                            mBitmapAlpha = null;                             // CreateFromHBitmap(FreeImage.GetHbitmap(bitmap_alpha, IntPtr.Zero, false));
                            FreeImage.UnloadEx(ref bitmap_alpha);
                        }

                        // Преобразуем
                        FIBITMAP bitmap_no_transparent = FreeImage.ConvertTo24Bits(mFreeImageBitmap);
                        if (!bitmap_no_transparent.IsNull)
                        {
                            mBitmapNoTransparent = null;                             // CreateFromHBitmap(FreeImage.GetHbitmap(bitmap_no_transparent, IntPtr.Zero, false));
                            FreeImage.UnloadEx(ref bitmap_no_transparent);
                        }

                        radioChannelAlpha.IsEnabled         = true;
                        radioChannelNoTransparent.IsEnabled = true;
                        if (radioChannelOriginal.IsChecked.Value)
                        {
                            mImagePresentator.Source = mBitmapOriginal;
                        }
                        else
                        {
                            radioChannelOriginal.IsChecked = true;
                        }
                    }
                    else
                    {
                        radioChannelAlpha.IsEnabled         = false;
                        radioChannelNoTransparent.IsEnabled = false;
                        if (radioChannelOriginal.IsChecked.Value)
                        {
                            mImagePresentator.Source = mBitmapOriginal;
                        }
                        else
                        {
                            radioChannelOriginal.IsChecked = true;
                        }
                    }

                    mImagePresentator.Width  = FreeImage.GetWidth(mFreeImageBitmap);
                    mImagePresentator.Height = FreeImage.GetHeight(mFreeImageBitmap);

                    if (mImagePresentator.Width > contentViewer.ViewportWidth - 30)
                    {
                        contentViewer.ContentScale = (contentViewer.ViewportWidth - 30) / mImagePresentator.Width;
                    }
                    else
                    {
                        contentViewer.ContentScale = 1.0;
                    }
                }
                catch (Exception exc)
                {
                    XLogger.LogExceptionModule(MODULE_NAME, exc);
                }

                // Always unload bitmap
                FreeImage.UnloadEx(ref mFreeImageBitmap);
            }
Exemple #3
0
        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);
        }
        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;
            }
        }