Example #1
0
        public void Example()
        {
            // Allocating a new bitmap with 99x99 pixels, 16-bit color depth and an allocation of 5 bits for each color.
            dib = FreeImage.Allocate(99, 99, 16, FreeImage.FI16_555_RED_MASK, FreeImage.FI16_555_GREEN_MASK, FreeImage.FI16_555_BLUE_MASK);

            // Saving bitmap.
            if (!FreeImage.SaveEx(ref dib, "example01.bmp", true))
            {
                Console.WriteLine("Saving 'example.bmp' failed.");
                FreeImage.UnloadEx(ref dib);
            }

            // Allocation a new bitmap with 71x33 pixels, 4-bit color depth. Bitmaps below 16-bit have paletts.
            // Each pixel references an index within the palette wich contains the true color.
            // Therefor no bit-masks are needed and can be set to 0.
            dib = FreeImage.Allocate(71, 33, 4, 0, 0, 0);

            // Saving bitmap.
            if (!FreeImage.SaveEx(ref dib, "example02.tif", true))
            {
                Console.WriteLine("Saving 'example02.tif' failed.");
                FreeImage.UnloadEx(ref dib);
            }

            // Allocation a new bitmap. This time 'AllocateT' is used because 'Allocate' can only create standard bitmaps.
            // In this case a RGBF bitmap is created. Red, green and blue are represented by a float-value so no bit-masks are needed.
            dib = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_RGBF, 50, 75, 9, 0, 0, 0);

            // Saving bitmap.
            if (!FreeImage.SaveEx(ref dib, "example03.hdr", true))
            {
                Console.WriteLine("Saving 'example03.hdr' failed.");
                FreeImage.UnloadEx(ref dib);
            }
        }
Example #2
0
        public bool Save(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return(false);
            }
            bool isHDR = false;

            System.IO.FileInfo fileInfo = new System.IO.FileInfo(path);
            if (fileInfo.Extension.ToLower().Contains(".hdr"))
            {
                isHDR = true;
            }

            FIBITMAP dib = new FIBITMAP();

            if (isHDR)
            {
                dib = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_RGBF, (int)width, (int)height, 96);

                uint h = FreeImage.GetHeight(dib);

                for (int i = 0; i < h; i++)
                {
                    Scanline <FIRGBF> scanline = new Scanline <FIRGBF>(dib, i);

                    FIRGBF[] data = scanline.Data;

                    for (int j = 0; j < data.Length; j++)
                    {
                        Color color = this.GetPixel(data.Length - 1 - j, i);
                        data[j].red   = color.r;
                        data[j].green = color.g;
                        data[j].blue  = color.b;
                    }

                    scanline.Data = data;
                }
            }
            else
            {
                FREE_IMAGE_FORMAT fif = FreeImage.GetFIFFromFilename(path);
                dib = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_BITMAP, (int)width, (int)height, 24);

                uint h = FreeImage.GetHeight(dib);
                for (int i = 0; i < h; i++)
                {
                    Scanline <RGBTRIPLE> scanline = new Scanline <RGBTRIPLE>(dib, i);

                    RGBTRIPLE[] data = scanline.Data;

                    for (int j = 0; j < data.Length; j++)
                    {
                        Color color = this.GetPixel(data.Length - 1 - j, i);
                        color.Gamma(0.45f);

                        int r = (int)(color.r * 255.0f);
                        int g = (int)(color.g * 255.0f);
                        int b = (int)(color.b * 255.0f);
                        if (r < 0)
                        {
                            r = 0;
                        }
                        if (r > 255)
                        {
                            r = 255;
                        }
                        if (g < 0)
                        {
                            g = 0;
                        }
                        if (g > 255)
                        {
                            g = 255;
                        }
                        if (b < 0)
                        {
                            b = 0;
                        }
                        if (b > 255)
                        {
                            b = 255;
                        }

                        data[j].rgbtRed   = (byte)r;
                        data[j].rgbtGreen = (byte)g;
                        data[j].rgbtBlue  = (byte)b;
                    }

                    scanline.Data = data;
                }
            }

            if (!FreeImage.SaveEx(ref dib, path, true))
            {
                FreeImage.UnloadEx(ref dib);
                return(false);
            }
            FreeImage.UnloadEx(ref dib);
            return(true);
        }
Example #3
0
        /// <summary>
        /// 保存贴图到文件,适用于 Chunk_CreateTexture2D 及 Chunk_CreateSwapBuffer
        /// </summary>
        /// <param name="subDatas"></param>
        /// <param name="desc"></param>
        /// <param name="section"></param>
        public static void SaveTextureToFile(D3D11_SUBRESOURCE_DATA[] subDatas, D3D11_TEXTURE2D_DESC desc, Section section, string path)
        {
            DXGI_FORMAT format = desc.Format;

            if (Common.IsBlockFormat(format)) // 暂时不支持导出压缩格式
            {
                return;
            }

            if (format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_SNORM ||
                format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_TYPELESS ||
                format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)    // 4通道保存成tga以方便编辑A通道
            {
                FIBITMAP bmp = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_BITMAP, (int)desc.Width, (int)desc.Height, 32);

                Debug.Assert(subDatas[0].sysMemLength >= desc.Width * desc.Height * 4); // sysMemLength 是对齐的,因此可能大于真实数据大小

                fixed(void *p = &section.uncompressedData[subDatas[0].sysMemDataOffset])
                {
                    byte *rawData = (byte *)p;

                    for (int h = (int)(desc.Height - 1); h >= 0; h--) // bitmap 存储方向与 dx 相反
                    {
                        byte *scanLine = (byte *)FreeImage.GetScanLine(bmp, h);
                        for (int w = 0; w < desc.Width; w++)
                        {
                            *scanLine++ = rawData[w * 4];
                            *scanLine++ = rawData[w * 4 + 1];
                            *scanLine++ = rawData[w * 4 + 2];
                            *scanLine++ = rawData[w * 4 + 3];
                        }

                        rawData += subDatas[0].SysMemPitch;
                    }
                }

                path = $"{path}.tga";
                File.Delete(path);
                FreeImage.Save(FREE_IMAGE_FORMAT.FIF_TARGA, bmp, path, FREE_IMAGE_SAVE_FLAGS.DEFAULT);
                FreeImage.Unload(bmp);
            }
            else if (format == DXGI_FORMAT.DXGI_FORMAT_R8_SNORM ||
                     format == DXGI_FORMAT.DXGI_FORMAT_R8_TYPELESS ||
                     format == DXGI_FORMAT.DXGI_FORMAT_R8_UNORM ||
                     format == DXGI_FORMAT.DXGI_FORMAT_A8_UNORM) // 经过测试单通道无论指定哪个通道数据都只存了一个通道, 单通道保存成png24
            {
                FIBITMAP bmp = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_BITMAP, (int)desc.Width, (int)desc.Height, 24);
                Debug.Assert(subDatas[0].sysMemLength >= desc.Width * desc.Height);
                fixed(void *p = &section.uncompressedData[subDatas[0].sysMemDataOffset])
                {
                    byte *rawData = (byte *)p;

                    for (int h = (int)(desc.Height - 1); h >= 0; h--) // bitmap 存储方向与 dx 相反
                    {
                        byte *scanLine = (byte *)FreeImage.GetScanLine(bmp, h);
                        for (int w = 0; w < desc.Width; w++)
                        {
                            byte val        = rawData[w];
                            *    scanLine++ = val;
                            *    scanLine++ = val;
                            *    scanLine++ = val;
                        }

                        rawData += subDatas[0].SysMemPitch;
                    }
                }

                path = $"{path}.bmp";
                File.Delete(path);
                FreeImage.Save(FREE_IMAGE_FORMAT.FIF_BMP, bmp, path, FREE_IMAGE_SAVE_FLAGS.BMP_SAVE_RLE);
                FreeImage.Unload(bmp);
            }
        }
        private static FIBITMAP NewFiBitMap(PixImage <float> pi)
        {
            FreeImageCheck(pi.Volume.Info);
            var  sx   = pi.Size.X;
            var  sy   = pi.Size.Y;
            var  data = pi.Volume.Data;
            long i    = pi.Volume.FirstIndex;
            long j    = pi.Volume.JY;

            switch (pi.ChannelCount)
            {
            case 1:
            {
                var dib   = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_FLOAT, sx, sy, 32);
                var delta = (int)FreeImage.GetPitch(dib);
                var bits  = FreeImage.GetBits(dib) + sy * delta;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        float *pixel = (float *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[x] = data[i++];
                        }
                    }
                    i += j;
                }
                return(dib);
            }

            case 3:
            {
                var dib   = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_RGBF, sx, sy, 96);
                var delta = (int)FreeImage.GetPitch(dib);
                var bits  = FreeImage.GetBits(dib) + sy * delta;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FIRGBF *pixel = (FIRGBF *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[x].red   = data[i++];
                            pixel[x].green = data[i++];
                            pixel[x].blue  = data[i++];
                        }
                    }
                    i += j;
                }
                return(dib);
            }

            case 4:
            {
                var dib   = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_RGBAF, sx, sy, 128);
                var delta = (int)FreeImage.GetPitch(dib);
                var bits  = FreeImage.GetBits(dib) + sy * delta;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FIRGBAF *pixel = (FIRGBAF *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[x].red   = data[i++];
                            pixel[x].green = data[i++];
                            pixel[x].blue  = data[i++];
                            pixel[x].alpha = data[i++];
                        }
                    }
                    i += j;
                }
                return(dib);
            }

            default:
                break;
            }
            throw new ArgumentException("cannot save PixImage");
        }
Example #5
0
        private bool MergeImages(string fileNameFormat, string outputDir, string prefix, int frameNum, string ext)
        {
            FreeImageBitmap combined        = null;
            string          fname           = "";
            bool            supported       = false;
            bool            mergeSuccessful = true;
            FREE_IMAGE_TYPE type            = FREE_IMAGE_TYPE.FIT_UNKNOWN;
            FreeImageBitmap source          = null;

            string mergedFile = string.Format(fileNameFormat, outputDir, prefix, frameNum, ext);
            string tempFile   = string.Format(fileNameFormat, outputDir, prefix, frameNum, "_tmp" + ext);

            // Allocate a bitmap to store the final image
            fname = string.Format(fileNameFormat, outputDir, "slice_0_" + prefix, frameNum, ext);

            try
            {
                source = new FreeImageBitmap(fname);

                if (source != null)
                {
                    type = source.ImageType;
                    switch (type)
                    {
                    case FREE_IMAGE_TYPE.FIT_BITMAP:
                        if (source.ColorDepth == 32 || source.ColorDepth == 24)
                        {
                            supported = true;
                        }
                        break;

                    case FREE_IMAGE_TYPE.FIT_RGB16:
                    case FREE_IMAGE_TYPE.FIT_RGBA16:
                    case FREE_IMAGE_TYPE.FIT_RGBAF:
                    case FREE_IMAGE_TYPE.FIT_RGBF:
                        supported = true;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Error opening slice file");
            }

            if (supported == false)
            {
                Console.WriteLine("Image format not supported");
                return(false);
            }

            try
            {
                // Create a new image of the input file type and the correct size
                FIBITMAP newImage = FreeImage.AllocateT(type, Width, Height, source.ColorDepth, source.RedMask, source.BlueMask, source.GreenMask);

                FreeImage.SaveEx(newImage, tempFile);
                FreeImage.UnloadEx(ref newImage);
                source.Dispose();
                source = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();
                combined = new FreeImageBitmap(tempFile);
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Error creating output file");
                mergeSuccessful = false;
            }

            for (int i = 0; i < SlicesAcross * SlicesDown; i++)
            {
                // Load the image slice
                fname = string.Format(fileNameFormat, outputDir, "slice_" + i + "_" + prefix, frameNum, ext);
                FreeImageBitmap slice = new FreeImageBitmap(fname);

                int posX;
                int posY;

                if (SlicesDown > 1 && SlicesAcross > 1)
                {
                    posX = i % SlicesAcross;
                    posY = i / SlicesAcross;
                }
                else if (SlicesDown == 1)
                {
                    posX = i;
                    posY = 0;
                }
                else
                {
                    posX = 0;
                    posY = i;
                }

                // Calculate the image slice sizes and the row/column position
                double sizeV    = (1.0 / SlicesDown) * Height;
                double sizeH    = (1.0 / SlicesAcross) * Width;
                double overlapV = sizeV * (Overlap / 100.0);
                double overlapH = sizeH * (Overlap / 100.0);

                double realLeft = sizeH * posX;
                double left     = realLeft - overlapH;

                double realTop = sizeV * posY;
                double top     = realTop - overlapV;

                // Check the sizes are within limits and adjust
                left = Math.Max(0.0, left);
                top  = Math.Max(0.0, top);

                try
                {
                    switch (type)
                    {
                    case FREE_IMAGE_TYPE.FIT_BITMAP:
                        if (slice.ColorDepth == 24)
                        {
                            for (int y = 0; y < slice.Height; y++)
                            {
                                int srcY  = (slice.Height - 1) - y;
                                int destY = (combined.Height - 1) - (srcY + (int)top);
                                int topY  = y + (int)top;
                                Scanline <RGBTRIPLE> srcLine  = (Scanline <RGBTRIPLE>)slice.GetScanline(y);
                                Scanline <RGBTRIPLE> destLine = (Scanline <RGBTRIPLE>)combined.GetScanline(destY);

                                for (int x = 0; x < slice.Width; x++)
                                {
                                    int destX = x + (int)left;

                                    // Make sure it's not out of bounds
                                    if (destY >= Height || destY >= Width)
                                    {
                                        continue;
                                    }
                                    // Is the pixel in an overlapping Area
                                    if (topY < realTop || destX < realLeft)
                                    {
                                        MergePixel srcPixel  = new MergePixel(srcLine[x].rgbtRed, srcLine[x].rgbtGreen, srcLine[x].rgbtBlue, 0);
                                        MergePixel destPixel = new MergePixel(destLine[destX].rgbtRed, destLine[destX].rgbtGreen, destLine[destX].rgbtBlue, 0);

                                        destPixel = CalculatePixelWeight(overlapV, overlapH, realLeft, left, realTop, top, y, topY, x, srcPixel, destPixel);

                                        RGBTRIPLE dest;
                                        dest.rgbtRed    = destPixel.red > 255.0 ? (byte)255 : (byte)destPixel.red;
                                        dest.rgbtGreen  = destPixel.green > 255.0 ? (byte)255 : (byte)destPixel.green;
                                        dest.rgbtBlue   = destPixel.blue > 255.0 ? (byte)255 : (byte)destPixel.blue;
                                        destLine[destX] = dest;
                                    }
                                    else
                                    {
                                        destLine[destX] = srcLine[x];
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (int y = 0; y < slice.Height; y++)
                            {
                                int srcY  = (slice.Height - 1) - y;
                                int destY = (combined.Height - 1) - (srcY + (int)top);
                                int topY  = y + (int)top;
                                Scanline <RGBQUAD> srcLine  = (Scanline <RGBQUAD>)slice.GetScanline(y);
                                Scanline <RGBQUAD> destLine = (Scanline <RGBQUAD>)combined.GetScanline(destY);

                                for (int x = 0; x < slice.Width; x++)
                                {
                                    int destX = x + (int)left;

                                    // Make sure it's not out of bounds
                                    if (destY >= Height || destY >= Width)
                                    {
                                        continue;
                                    }
                                    // Is the pixel in an overlapping Area
                                    if (topY < realTop || destX < realLeft)
                                    {
                                        MergePixel srcPixel  = new MergePixel(srcLine[x].rgbRed, srcLine[x].rgbGreen, srcLine[x].rgbBlue, destLine[destX].rgbReserved);
                                        MergePixel destPixel = new MergePixel(destLine[destX].rgbRed, destLine[destX].rgbGreen, destLine[destX].rgbBlue, destLine[destX].rgbReserved);

                                        destPixel = CalculatePixelWeight(overlapV, overlapH, realLeft, left, realTop, top, y, topY, x, srcPixel, destPixel);

                                        RGBQUAD dest = new RGBQUAD();
                                        dest.rgbRed      = destPixel.red > 255.0 ? (byte)255 : (byte)destPixel.red;
                                        dest.rgbGreen    = destPixel.green > 255.0 ? (byte)255 : (byte)destPixel.green;
                                        dest.rgbBlue     = destPixel.blue > 255.0 ? (byte)255 : (byte)destPixel.blue;
                                        dest.rgbReserved = destPixel.alpha > 255.0 ? (byte)255 : (byte)destPixel.alpha;
                                        destLine[destX]  = dest;
                                    }
                                    else
                                    {
                                        destLine[destX] = srcLine[x];
                                    }
                                }
                            }
                        }
                        break;

                    case FREE_IMAGE_TYPE.FIT_RGB16:
                        for (int y = 0; y < slice.Height; y++)
                        {
                            int srcY  = (slice.Height - 1) - y;
                            int destY = (combined.Height - 1) - (srcY + (int)top);
                            int topY  = y + (int)top;
                            Scanline <FIRGB16> srcLine  = (Scanline <FIRGB16>)slice.GetScanline(y);
                            Scanline <FIRGB16> destLine = (Scanline <FIRGB16>)combined.GetScanline(destY);

                            for (int x = 0; x < slice.Width; x++)
                            {
                                int destX = x + (int)left;

                                // Make sure it's not out of bounds
                                if (destY >= Height || destY >= Width)
                                {
                                    continue;
                                }
                                // Is the pixel in an overlapping Area
                                if (topY < realTop || destX < realLeft)
                                {
                                    MergePixel srcPixel  = new MergePixel(srcLine[x].red, srcLine[x].green, srcLine[x].blue, 0);
                                    MergePixel destPixel = new MergePixel(destLine[destX].red, destLine[destX].green, destLine[destX].blue, 0);

                                    destPixel = CalculatePixelWeight(overlapV, overlapH, realLeft, left, realTop, top, y, topY, x, srcPixel, destPixel);

                                    FIRGB16 dest = new FIRGB16();
                                    dest.red        = (ushort)destPixel.red;
                                    dest.green      = (ushort)destPixel.green;
                                    dest.blue       = (ushort)destPixel.blue;
                                    destLine[destX] = dest;
                                }
                                else
                                {
                                    destLine[destX] = srcLine[x];
                                }
                            }
                        }
                        break;

                    case FREE_IMAGE_TYPE.FIT_RGBA16:
                        for (int y = 0; y < slice.Height; y++)
                        {
                            int srcY  = (slice.Height - 1) - y;
                            int destY = (combined.Height - 1) - (srcY + (int)top);
                            int topY  = y + (int)top;
                            Scanline <FIRGBA16> srcLine  = (Scanline <FIRGBA16>)slice.GetScanline(y);
                            Scanline <FIRGBA16> destLine = (Scanline <FIRGBA16>)combined.GetScanline(destY);

                            for (int x = 0; x < slice.Width; x++)
                            {
                                int destX = x + (int)left;

                                // Make sure it's not out of bounds
                                if (destY >= Height || destY >= Width)
                                {
                                    continue;
                                }
                                // Is the pixel in an overlapping Area
                                if (topY < realTop || destX < realLeft)
                                {
                                    MergePixel srcPixel  = new MergePixel(srcLine[x].red, srcLine[x].green, srcLine[x].blue, srcLine[x].alpha);
                                    MergePixel destPixel = new MergePixel(destLine[destX].red, destLine[destX].green, destLine[destX].blue, destLine[destX].alpha);

                                    destPixel = CalculatePixelWeight(overlapV, overlapH, realLeft, left, realTop, top, y, topY, x, srcPixel, destPixel);

                                    FIRGBA16 dest = new FIRGBA16();
                                    dest.red        = (ushort)destPixel.red;
                                    dest.green      = (ushort)destPixel.green;
                                    dest.blue       = (ushort)destPixel.blue;
                                    dest.alpha      = (ushort)destPixel.alpha;
                                    destLine[destX] = dest;
                                }
                                else
                                {
                                    destLine[destX] = srcLine[x];
                                }
                            }
                        }
                        break;

                    case FREE_IMAGE_TYPE.FIT_RGBAF:
                        for (int y = 0; y < slice.Height; y++)
                        {
                            int srcY  = (slice.Height - 1) - y;
                            int destY = (combined.Height - 1) - (srcY + (int)top);
                            int topY  = y + (int)top;
                            Scanline <FIRGBAF> srcLine  = (Scanline <FIRGBAF>)slice.GetScanline(y);
                            Scanline <FIRGBAF> destLine = (Scanline <FIRGBAF>)combined.GetScanline(destY);

                            for (int x = 0; x < slice.Width; x++)
                            {
                                int destX = x + (int)left;

                                // Make sure it's not out of bounds
                                if (destY >= Height || destY >= Width)
                                {
                                    continue;
                                }
                                // Is the pixel in an overlapping Area
                                if (topY < realTop || destX < realLeft)
                                {
                                    MergePixel srcPixel  = new MergePixel(srcLine[x].red, srcLine[x].green, srcLine[x].blue, destLine[destX].alpha);
                                    MergePixel destPixel = new MergePixel(destLine[destX].red, destLine[destX].green, destLine[destX].blue, destLine[destX].alpha);

                                    destPixel = CalculatePixelWeight(overlapV, overlapH, realLeft, left, realTop, top, y, topY, x, srcPixel, destPixel);

                                    FIRGBAF dest = new FIRGBAF();
                                    dest.red        = (float)destPixel.red;
                                    dest.green      = (float)destPixel.green;
                                    dest.blue       = (float)destPixel.blue;
                                    dest.alpha      = (float)destPixel.alpha;
                                    destLine[destX] = dest;
                                }
                                else
                                {
                                    destLine[destX] = srcLine[x];
                                }
                            }
                        }
                        break;

                    case FREE_IMAGE_TYPE.FIT_RGBF:
                        for (int y = 0; y < slice.Height; y++)
                        {
                            int srcY  = (slice.Height - 1) - y;
                            int destY = (combined.Height - 1) - (srcY + (int)top);
                            int topY  = y + (int)top;
                            Scanline <FIRGBF> srcLine  = (Scanline <FIRGBF>)slice.GetScanline(y);
                            Scanline <FIRGBF> destLine = (Scanline <FIRGBF>)combined.GetScanline(destY);

                            for (int x = 0; x < slice.Width; x++)
                            {
                                int destX = x + (int)left;

                                // Make sure it's not out of bounds
                                if (destY >= Height || destY >= Width)
                                {
                                    continue;
                                }
                                // Is the pixel in an overlapping Area
                                if (topY < realTop || destX < realLeft)
                                {
                                    MergePixel srcPixel  = new MergePixel(srcLine[x].red, srcLine[x].green, srcLine[x].blue, 0);
                                    MergePixel destPixel = new MergePixel(destLine[destX].red, destLine[destX].green, destLine[destX].blue, 0);

                                    destPixel = CalculatePixelWeight(overlapV, overlapH, realLeft, left, realTop, top, y, topY, x, srcPixel, destPixel);

                                    FIRGBF dest = new FIRGBF();
                                    dest.red        = (float)destPixel.red;
                                    dest.green      = (float)destPixel.green;
                                    dest.blue       = (float)destPixel.blue;
                                    destLine[destX] = dest;
                                }
                                else
                                {
                                    destLine[destX] = srcLine[x];
                                }
                            }
                        }
                        break;
                    }
                    slice.Dispose();
                }
                catch (Exception ex)
                {
                    logger.Error(ex, "Error merging image files");
                    mergeSuccessful = false;
                }
            }
            try
            {
                if (mergeSuccessful)
                {
                    combined.Save(mergedFile);
                    combined.Dispose();
                    combined = null;
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                    File.Delete(tempFile);
                }
                else
                {
                    Log += DateTime.Now.ToLongTimeString() + " Merging frame " + frameNum + " failed.\n";
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex, "Error writing combined file");
                mergeSuccessful = false;
            }

            return(mergeSuccessful);
        }