public void FIRGBF()
        {
            FIRGBF rgb = new FIRGBF();

            Assert.AreEqual(0 / 255f, rgb.blue);
            Assert.AreEqual(0 / 255f, rgb.green);
            Assert.AreEqual(0 / 255f, rgb.red);

            rgb = new FIRGBF(Color.Chartreuse);
            Assert.That(EqualColors(Color.Chartreuse, rgb.Color));

            rgb = new FIRGBF(Color.FromArgb(133, 83, 95, 173));
            Assert.AreEqual(173 / 255f, rgb.blue);
            Assert.AreEqual(95 / 255f, rgb.green);
            Assert.AreEqual(83 / 255f, rgb.red);

            rgb.Color = Color.Crimson;
            Assert.That(EqualColors(Color.Crimson, rgb.Color));

            rgb.Color = Color.MidnightBlue;
            Assert.That(EqualColors(Color.MidnightBlue, rgb.Color));

            rgb.Color = Color.White;
            Assert.AreEqual(255 / 255f, rgb.blue);
            Assert.AreEqual(255 / 255f, rgb.green);
            Assert.AreEqual(255 / 255f, rgb.red);

            rgb.Color = Color.Black;
            Assert.AreEqual(0 / 255f, rgb.blue);
            Assert.AreEqual(0 / 255f, rgb.green);
            Assert.AreEqual(0 / 255f, rgb.red);

            rgb = Color.DarkGoldenrod;
            Color color = rgb;

            Assert.That(EqualColors(Color.DarkGoldenrod, color));
        }
Beispiel #2
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);
        }