Exemple #1
0
        static void Main(string[] args)
        {
            // load image, this can by your 16-bit tif
            FIBITMAP dib = FreeImage.LoadEx("myfile.tif");

            // convert to 8-bits
            dib = FreeImage.ConvertToGreyscale(dib);
            // rotate image by 90 degrees
            dib = FreeImage.Rotate(dib, 90);
            // save image
            FreeImage.SaveEx(dib, "newfile.png");
            // unload bitmap
            FreeImage.UnloadEx(ref dib);
        }
    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);
    }
Exemple #3
0
        // Сохраняет выделенные файлы в TIFF
        private void btnTIFF_Click(object sender, EventArgs e)
        {
            if (0 == listView1.SelectedItems.Count)
            {
                return;
            }

            bool deleteFiles = chkDeleteFiles.Checked;             // Удалять jpeg'и после создания tiff

            savePDFDialog.Filter           = "Файлы TIFF|*.tif;*.tiff";
            savePDFDialog.InitialDirectory = PDFInitialDir;
            if (DialogResult.OK != savePDFDialog.ShowDialog())
            {
                return;
            }

            Cursor.Current = Cursors.WaitCursor;

            // Вариант с FreeImage - быстро, но сложнее и иногда инвертирует цвета

            // Сохранить первую страницу
            FIBITMAP dib_color = FreeImage.LoadEx(scanFileNames[listView1.SelectedItems[0].Index]);

            FIBITMAP dib = FreeImage.ConvertToGreyscale(dib_color);

            FreeImage.UnloadEx(ref dib_color);
            if (FREE_IMAGE_COLOR_TYPE.FIC_MINISBLACK == FreeImage.GetColorType(dib))
            {
                FreeImage.Invert(dib);
            }

            deleteFiles = FreeImage.SaveEx(ref dib, savePDFDialog.FileName,
                                           FREE_IMAGE_FORMAT.FIF_TIFF, FREE_IMAGE_SAVE_FLAGS.TIFF_CCITTFAX4, FREE_IMAGE_COLOR_DEPTH.FICD_01_BPP, true);
            FreeImage.UnloadEx(ref dib);

            if (listView1.SelectedItems.Count > 1)
            {
                string        tmpFile = Path.GetTempFileName() + ".tif";
                FIBITMAP      fib;
                FIBITMAP      fib_color;
                FIMULTIBITMAP fmb = FreeImage.OpenMultiBitmapEx(savePDFDialog.FileName);
                // Добавить остальные страницы
                for (int i = 1; i < listView1.SelectedItems.Count; i++)
                {
                    fib_color = FreeImage.LoadEx(scanFileNames[listView1.SelectedItems[i].Index]);
                    fib       = FreeImage.ConvertToGreyscale(fib_color);
                    FreeImage.UnloadEx(ref fib_color);

                    if (FREE_IMAGE_COLOR_TYPE.FIC_MINISBLACK == FreeImage.GetColorType(fib))
                    {
                        FreeImage.Invert(fib);
                    }

                    FreeImage.SaveEx(ref fib, tmpFile,
                                     FREE_IMAGE_FORMAT.FIF_TIFF, FREE_IMAGE_SAVE_FLAGS.TIFF_CCITTFAX4, FREE_IMAGE_COLOR_DEPTH.FICD_01_BPP, true);
                    fib = FreeImageAPI.FreeImage.LoadEx(tmpFile);

                    FreeImage.AppendPage(fmb, fib);
                    FreeImage.UnloadEx(ref fib);
                    File.Delete(tmpFile);
                }
                deleteFiles = FreeImage.CloseMultiBitmapEx(ref fmb);
            }

            /*
             * // Вариант с ImageMagick - проще, но очень медленно
             * int s = 0;
             *
             * MagickImageCollection images = new MagickImageCollection();
             * foreach (ListViewItem item in listView1.SelectedItems)
             * {
             *      images.Add(scanFileNames[item.Index]);
             *      images[s].Strip(); // По аналогии с PDF на всякий случай
             *      images[s].Format = MagickFormat.Tif;
             *      images[s].Settings.Compression = CompressionMethod.Group4;
             *      images[s].Depth = 1;
             *      s++;
             * }
             * try
             * {
             *      images.Write(savePDFDialog.FileName, MagickFormat.Tif);
             * }
             * catch (MagickException me)
             * {
             *      toolStripStatus.Text = me.Message;
             *      deleteFiles = false;
             * }
             * images.Dispose();
             */
            if (deleteFiles)
            {
                btnDelete_Click(btnPDF, null);
            }

            Cursor.Current = Cursors.Default;
        }