Exemplo n.º 1
0
        public void FIRGB16()
        {
            FIRGB16 rgb = new FIRGB16();
            Assert.AreEqual(0 * 256, rgb.blue);
            Assert.AreEqual(0 * 256, rgb.green);
            Assert.AreEqual(0 * 256, rgb.red);

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

            rgb = new FIRGB16(Color.FromArgb(133, 83, 95, 173));
            Assert.AreEqual(173 * 256, rgb.blue);
            Assert.AreEqual(95 * 256, rgb.green);
            Assert.AreEqual(83 * 256, 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 * 256, rgb.blue);
            Assert.AreEqual(255 * 256, rgb.green);
            Assert.AreEqual(255 * 256, rgb.red);

            rgb.Color = Color.Black;
            Assert.AreEqual(0 * 256, rgb.blue);
            Assert.AreEqual(0 * 256, rgb.green);
            Assert.AreEqual(0 * 256, rgb.red);

            rgb = Color.DarkGoldenrod;
            Color color = rgb;
            Assert.That(EqualColors(Color.DarkGoldenrod, color));
        }
Exemplo n.º 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;
        }