Inheritance: IDisposable
Esempio n. 1
0
 /// <summary>
 /// One-liner to save Bitmaps to JPEG using LibJpeg.
 /// </summary>
 /// <param name="image">Bitmap</param>
 /// <param name="filename">Path to save to. Creates or overwrites if existing.</param>
 /// <param name="compression">Compression parameters.</param>
 public void Save(Bitmap image, string filename, CompressionParameters compression = null)
 {
     using (var jpeg = new JpegImage(image))
     {
         jpeg.Save(filename, compression);
     }
 }
Esempio n. 2
0
        public Image Decode(Stream stream)
        {
            JpegImage jpg = new JpegImage(stream);

            int pixelWidth = jpg.Width;
            int pixelHeight = jpg.Height;

            byte[] pixels = new byte[pixelWidth * pixelHeight * 4];

            if (!(jpg.Colorspace == Colorspace.RGB && jpg.BitsPerComponent == 8))
            {
                throw new NotSupportedException("JpegDecoder only support RGB color space.");
            }

            for (int y = 0; y < pixelHeight; y++)
            {
                SampleRow row = jpg.GetRow(y);

                for (int x = 0; x < pixelWidth; x++)
                {
                    Sample sample = row.GetAt(x);
                    
                    int offset = (y * pixelWidth + x) * 4;

                    pixels[offset + 0] = (byte)sample[2];
                    pixels[offset + 1] = (byte)sample[1];
                    pixels[offset + 2] = (byte)sample[0];
                    pixels[offset + 3] = (byte)255;
                }
            }

            return new Image(pixelWidth, pixelHeight, pixels);
        }
Esempio n. 3
0
        public void Encode(Image image, Stream stream)
        {
            int pixelWidth  = image.Width;
            int pixelHeight = image.Height;

            byte[] sourcePixels = image.Pixels;

            SampleRow[] rows = new SampleRow[pixelHeight];

            for (int y = 0; y < pixelHeight; y++)
            {
                byte[] samples = new byte[pixelWidth * 3];

                for (int x = 0; x < pixelWidth; x++)
                {
                    int start = x * 3;
                    int source = (y * pixelWidth + x) * 4;

                    samples[start] = sourcePixels[source + 2];
                    samples[start + 1] = sourcePixels[source + 1];
                    samples[start + 2] = sourcePixels[source];
                }

                rows[y] = new SampleRow(samples, pixelWidth, 8, 3);
            }

            JpegImage jpg = new JpegImage(rows, Colorspace.RGB);
            jpg.WriteJpeg(stream, new CompressionParameters { Quality = Quality });
        }
Esempio n. 4
0
        /// <inheritdoc/>
        public void Encode(ImageBase image, Stream stream)
        {
            Guard.NotNull(image, nameof(image));
            Guard.NotNull(stream, nameof(stream));

            int imageWidth = image.Width;
            int imageHeight = image.Height;

            SampleRow[] rows = new SampleRow[imageHeight];

            Parallel.For(
                0,
                imageHeight,
                y =>
                    {
                        byte[] samples = new byte[imageWidth * 3];

                        for (int x = 0; x < imageWidth; x++)
                        {
                            Bgra32 color = Color.ToNonPremultiplied(image[x, y]);

                            int start = x * 3;
                            samples[start] = color.R;
                            samples[start + 1] = color.G;
                            samples[start + 2] = color.B;
                        }

                        rows[y] = new SampleRow(samples, imageWidth, 8, 3);
                    });

            using (JpegImage jpg = new JpegImage(rows, Colorspace.RGB))
            {
                jpg.WriteJpeg(stream, new CompressionParameters { Quality = this.Quality });
            }
        }
Esempio n. 5
0
		/// <summary>
		/// One-liner to save Bitmaps to JPEG using LibJpeg.
		/// </summary>
		/// <param name="image">Bitmap</param>
		/// <param name="filename">Path to save to. Creates or overwrites if existing.</param>
		/// <param name="compression">Compression parameters.</param>
		public void Save(Bitmap image, string filename, CompressionParameters compression = null)
		{
			using(var jpeg = new JpegImage(image))
			{
				jpeg.Save(filename, compression);
			}
		}
Esempio n. 6
0
 public override Image Load(Stream s)
 {
     BitMiracle.LibJpeg.JpegImage j = new BitMiracle.LibJpeg.JpegImage(s);
     Image i = (Image)j.ToBitmap();
     j.Dispose();
     System.GC.Collect();
     return i;
 }
Esempio n. 7
0
        public override Image Load(Stream s)
        {
            BitMiracle.LibJpeg.JpegImage j = new BitMiracle.LibJpeg.JpegImage(s);
            Image i = (Image)j.ToBitmap();

            j.Dispose();
            System.GC.Collect();
            return(i);
        }
Esempio n. 8
0
        public override void Save(Image i, Stream dest)
        {
            BitMiracle.LibJpeg.JpegImage j = BitMiracle.LibJpeg.JpegImage.FromBitmap((System.Drawing.Bitmap)i);
            CompressionParameters        c = new CompressionParameters();

            c.Quality           = 100;
            c.SimpleProgressive = false;
            j.WriteJpeg(dest, c);
            j.Dispose();
            System.GC.Collect();
        }
Esempio n. 9
0
        public void TestDecompressionFromCMYKJpeg()
        {
            using (JpegImage jpeg = new JpegImage(m_testcase + "ammerland.jpg"))
            {
                Assert.AreEqual(jpeg.BitsPerComponent, 8);
                Assert.AreEqual(jpeg.ComponentsPerSample, 4);
                Assert.AreEqual(jpeg.Colorspace, Colorspace.CMYK);
                Assert.AreEqual(jpeg.Width, 315);
                Assert.AreEqual(jpeg.Height, 349);

                testBitmapOutput(jpeg, "ammerland.bmp", m_expectedResults);
            }
        }
Esempio n. 10
0
        public void TestCompressionResultsSameAsForCJpeg()
        {
            using (JpegImage jpeg = new JpegImage(Path.Combine(m_testcase, "test24.bmp")))
            {
                testJpegOutput(jpeg, "test24.jpg", m_expectedResults);

                CompressionParameters parameters = new CompressionParameters();
                parameters.Quality = 25;
                testJpegOutput(jpeg, parameters, "test24_25.jpg", m_expectedResults);

                parameters = new CompressionParameters();
                parameters.SimpleProgressive = true;
                testJpegOutput(jpeg, parameters, "test24_prog.jpg", m_expectedResults);
            }
        }
Esempio n. 11
0
        private static JpegImage createImageFromPixels()
        {
            byte[] rowData = new byte[96];
            for (int i = 0; i < rowData.Length; ++i)
            {
                if (i < 5)
                    rowData[i] = 0xE4;
                else if (i < 15)
                    rowData[i] = 0xAB;
                else if (i < 35)
                    rowData[i] = 0x00;
                else if (i < 55)
                    rowData[i] = 0x65;
                else
                    rowData[i] = 0xF0;
            }

            const int width = 24;
            const int height = 25;
            const byte bitsPerComponent = 8;
            const byte componentsPerSample = 4;
            const Colorspace colorspace = Colorspace.CMYK;

            SampleRow row = new SampleRow(rowData, width, bitsPerComponent, componentsPerSample);
            SampleRow[] rows = new SampleRow[height];
            for (int i = 0; i < rows.Length; ++i)
                rows[i] = row;

            JpegImage jpegImage = new JpegImage(rows, colorspace);
            Assert.AreEqual(jpegImage.Width, width);
            Assert.AreEqual(jpegImage.Height, rows.Length);
            Assert.AreEqual(jpegImage.BitsPerComponent, bitsPerComponent);
            Assert.AreEqual(jpegImage.ComponentsPerSample, componentsPerSample);
            Assert.AreEqual(jpegImage.Colorspace, colorspace);
            return jpegImage;
        }
 internal DecompressorToJpegImage(JpegImage jpegImage)
 {
     m_jpegImage = jpegImage;
 }
 internal DecompressorToJpegImage(JpegImage jpegImage)
 {
     m_jpegImage = jpegImage;
 }
Esempio n. 14
0
 private static void testBitmapFromFile(string sourceFileName, string bitmapFileName, string folderWithExpectedResults)
 {
     using (JpegImage jpeg = new JpegImage(sourceFileName))
     {
         testBitmapOutput(jpeg, bitmapFileName, folderWithExpectedResults);
     }
 }
Esempio n. 15
0
        private static void testBitmapOutput(JpegImage jpeg, string bitmapFileName, string folderWithExpectedResults)
        {
            using (FileStream output = new FileStream(bitmapFileName, FileMode.Create))
                jpeg.WriteBitmap(output);

            FileAssert.AreEqual(bitmapFileName, Path.Combine(folderWithExpectedResults, bitmapFileName));
        }
Esempio n. 16
0
 private static void testJpegOutput(JpegImage jpeg, string jpegFileName, string folderWithExpectedResults)
 {
     testJpegOutput(jpeg, new CompressionParameters(), jpegFileName, folderWithExpectedResults);
 }
Esempio n. 17
0
        private static void testJpegOutput(JpegImage jpeg, CompressionParameters parameters, string jpegFileName, string folderWithExpectedResults)
        {
            using (FileStream output = new FileStream(jpegFileName, FileMode.Create))
                jpeg.WriteJpeg(output, parameters);

            FileAssert.AreEqual(jpegFileName, Path.Combine(folderWithExpectedResults, jpegFileName));
        }
Esempio n. 18
0
		private static void testJpegOutput(JpegImage jpeg, string jpegFileName, string folderWithExpectedResults)
		{
			testJpegOutput(jpeg, new CompressionParameters { Subsampling = Subsampling.LowDetail_4_1_1 }, jpegFileName, folderWithExpectedResults);
		}
Esempio n. 19
0
 private static void testJpegFromFile(string fileName, string jpegFileName, string folderWithExpectedResults)
 {
     using (JpegImage jpeg = new JpegImage(fileName))
     {
         testJpegOutput(jpeg, jpegFileName, folderWithExpectedResults);
     }
 }
Esempio n. 20
0
        /// <summary>
        /// Decodes the image from the specified stream and sets
        /// the data to image.
        /// </summary>
        /// <param name="image">The image, where the data should be set to.
        /// Cannot be null (Nothing in Visual Basic).</param>
        /// <param name="stream">The stream, where the image should be
        /// decoded from. Cannot be null (Nothing in Visual Basic).</param>
        /// <exception cref="System.ArgumentNullException">
        /// 	<para><paramref name="image"/> is null (Nothing in Visual Basic).</para>
        /// 	<para>- or -</para>
        /// 	<para><paramref name="stream"/> is null (Nothing in Visual Basic).</para>
        /// </exception>
        public void Decode(Image image, Stream stream)
        {
            Guard.NotNull(image, "image");
            Guard.NotNull(stream, "stream");
            JpegImage jpg = new JpegImage(stream);

            int pixelWidth = jpg.Width;
            int pixelHeight = jpg.Height;

            float[] pixels = new float[pixelWidth * pixelHeight * 4];

            if (jpg.Colorspace == Colorspace.RGB && jpg.BitsPerComponent == 8)
            {
                Parallel.For(
                    0,
                    pixelHeight,
                    y =>
                        {
                            SampleRow row = jpg.GetRow(y);

                            for (int x = 0; x < pixelWidth; x++)
                            {
                                Sample sample = row.GetAt(x);

                                int offset = ((y * pixelWidth) + x) * 4;

                                pixels[offset + 0] = sample[0] / 255f;
                                pixels[offset + 1] = sample[1] / 255f;
                                pixels[offset + 2] = sample[2] / 255f;
                                pixels[offset + 3] = 1;
                            }
                        });
            }
            else if (jpg.Colorspace == Colorspace.Grayscale && jpg.BitsPerComponent == 8)
            {
                Parallel.For(
                    0,
                    pixelHeight,
                    y =>
                    {
                        SampleRow row = jpg.GetRow(y);

                        for (int x = 0; x < pixelWidth; x++)
                        {
                            Sample sample = row.GetAt(x);

                            int offset = ((y * pixelWidth) + x) * 4;

                            pixels[offset + 0] = sample[0] / 255f;
                            pixels[offset + 1] = sample[0] / 255f;
                            pixels[offset + 2] = sample[0] / 255f;
                            pixels[offset + 3] = 1;
                        }
                    });
            }
            else
            {
                throw new NotSupportedException("JpegDecoder only supports RGB and Grayscale color spaces.");
            }

            image.SetPixels(pixelWidth, pixelHeight, pixels);

            jpg.Dispose();
        }
Esempio n. 21
0
        public void TestCreateFromPixelsAndRecompress()
        {
            using (JpegImage jpegImage = createImageFromPixels())
            {
                CompressionParameters compressionParameters = new CompressionParameters();
                compressionParameters.Quality = 20;
                const string output = "JpegImageFromPixels_20.jpg";
                testJpegOutput(jpegImage, compressionParameters, output, m_expectedResults);

                using (JpegImage recompressedImage = new JpegImage(output))
                {
                    Assert.AreEqual(recompressedImage.Colorspace, jpegImage.Colorspace);
                }
            }
        }
Esempio n. 22
0
 public void TestGrayscaleJpegToBitmap()
 {
     using (JpegImage jpegImage = new JpegImage(m_testcase + "turkey.jpg"))
     {
         testBitmapOutput(jpegImage, "turkey.png", m_expectedResults);
     }
 }
Esempio n. 23
0
        internal static void Decode(
            DicomPixelData oldPixelData,
            DicomPixelData newPixelData,
            DicomJpegParams parameters)
        {
            var pixelCount = oldPixelData.Height * oldPixelData.Width;

            if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrIct
                || newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrRct)
            {
                newPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb;
            }

            if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422
                || newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial422)
            {
                newPixelData.PhotometricInterpretation = PhotometricInterpretation.YbrFull;
            }

            if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull)
            {
                newPixelData.PlanarConfiguration = PlanarConfiguration.Planar;
            }

            for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++)
            {
                var jpegData = oldPixelData.GetFrame(frame);

                // Destination frame should be of even length
                var frameSize = newPixelData.UncompressedFrameSize;
                if ((frameSize & 1) == 1) ++frameSize;
                var destArray = new byte[frameSize];

                using (var stream = new MemoryStream(jpegData.Data))
                {
                    var decoder = new JpegImage(stream);
                    var w = decoder.Width;
                    var h = decoder.Height;

                    for (var c = 0; c < decoder.ComponentsPerSample; c++)
                    {
                        var pos = newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? (c * pixelCount) : c;
                        var offset = newPixelData.PlanarConfiguration == PlanarConfiguration.Planar
                                         ? 1
                                         : decoder.ComponentsPerSample;

                        if (newPixelData.BytesAllocated == 1)
                        {
                            for (var y = 0; y < h; ++y)
                            {
                                var row = decoder.GetRow(y);
                                for (var x = 0; x < w; ++x)
                                {
                                    destArray[pos] = (byte)row[x][c];
                                    pos += offset;
                                }
                            }
                        }
#if SUPPORT16BIT
                        else if (newPixelData.BytesAllocated == 2)
                        {
                            var destArray16 = new short[frameSize >> 1];
                            for (var y = 0; y < h; ++y)
                            {
                                var row = decoder.GetRow(y);
                                for (var x = 0; x < w; ++x)
                                {
                                    destArray16[pos] = row[x][c];
                                    pos += offset;
                                }
                            }

                            Buffer.BlockCopy(destArray16, 0, destArray, 0, frameSize);
                        }
#endif
                        else
                        {
                            throw new InvalidOperationException(
                                $"JPEG module does not support Bits Allocated == {newPixelData.BitsAllocated}!");
                        }
                    }

                    newPixelData.AddFrame(new MemoryByteBuffer(destArray));
                }
            }
        }
Esempio n. 24
0
        internal static void Encode(
            DicomPixelData oldPixelData,
            DicomPixelData newPixelData,
            DicomJpegParams parameters)
        {
            if ((oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422)
                || (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial422)
                || (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial420))
            {
                throw new InvalidOperationException(
                    "Photometric Interpretation '" + oldPixelData.PhotometricInterpretation
                    + "' not supported by JPEG encoder");
            }

            var w = oldPixelData.Width;
            var h = oldPixelData.Height;

            for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++)
            {
                var frameData = oldPixelData.GetFrame(frame);

                var nc = oldPixelData.SamplesPerPixel;
                var sgnd = oldPixelData.PixelRepresentation == PixelRepresentation.Signed;

                var rows = Enumerable.Range(0, h).Select(i => new short[w, nc]).ToArray();

                for (var c = 0; c < nc; c++)
                {
                    var pos = oldPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? (c * w * h) : c;
                    var offset = oldPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? 1 : nc;

                    if (oldPixelData.BytesAllocated == 1)
                    {
                        var data = frameData.Data;
                        if (sgnd)
                        {
                            if (oldPixelData.BitsStored < 8)
                            {
                                var sign = (byte)(1 << oldPixelData.HighBit);
                                var mask = (byte)(0xff >> (oldPixelData.BitsAllocated - oldPixelData.BitsStored));
                                for (var y = 0; y < h; ++y)
                                {
                                    for (var x = 0; x < w; ++x)
                                    {
                                        var pixel = (sbyte)data[pos];
                                        rows[y][x, c] = (short)((pixel & sign) > 0 ? -(((-pixel) & mask) + 1) : pixel);
                                        pos += offset;
                                    }
                                }
                            }
                            else
                            {
                                for (var y = 0; y < h; ++y)
                                {
                                    for (var x = 0; x < w; ++x)
                                    {
                                        rows[y][x, c] = (sbyte)data[pos];
                                        pos += offset;
                                    }
                                }
                            }
                        }
                        else
                        {
                            for (var y = 0; y < h; ++y)
                            {
                                for (var x = 0; x < w; ++x)
                                {
                                    rows[y][x, c] = data[pos];
                                    pos += offset;
                                }
                            }
                        }
                    }
#if SUPPORT16BIT
                    else if (oldPixelData.BytesAllocated == 2)
                    {
                        if (sgnd)
                        {
                            if (oldPixelData.BitsStored < 16)
                            {
                                var frameData16 = new ushort[w * h];
                                Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size);

                                var sign = (ushort)(1 << oldPixelData.HighBit);
                                var mask = (ushort)(0xffff >> (oldPixelData.BitsAllocated - oldPixelData.BitsStored));
                                for (var y = 0; y < h; ++y)
                                {
                                    for (var x = 0; x < w; ++x)
                                    {
                                        var pixel = frameData16[pos];
                                        rows[y][x, c] = (short)((pixel & sign) > 0 ? -(((-pixel) & mask) + 1) : pixel);
                                        pos += offset;
                                    }
                                }
                            }
                            else
                            {
                                var frameData16 = new short[w * h];
                                Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size);

                                for (var y = 0; y < h; ++y)
                                {
                                    for (var x = 0; x < w; ++x)
                                    {
                                        rows[y][x, c] = frameData16[pos];
                                        pos += offset;
                                    }
                                }
                            }
                        }
                        else
                        {
                            var frameData16 = new ushort[w * h];
                            Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size);

                            for (var y = 0; y < h; ++y)
                            {
                                for (var x = 0; x < w; ++x)
                                {
                                    rows[y][x, c] = (short)frameData16[pos];
                                    pos += offset;
                                }
                            }
                        }
                    }
#endif
                    else
                    {
                        throw new InvalidOperationException(
                            $"JPEG codec does not support Bits Allocated == {oldPixelData.BitsAllocated}");
                    }
                }

                try
                {
                    using (var stream = new MemoryStream())
                    {
                        var sampleRows =
                            rows.Select(
                                row =>
                                new SampleRow(
                                    ToRawRow(row, oldPixelData.BitsAllocated),
                                    w,
                                    (byte)oldPixelData.BitsStored,
                                    (byte)nc)).ToArray();
                        var colorSpace = GetColorSpace(oldPixelData.PhotometricInterpretation);
                        using (var encoder = new JpegImage(sampleRows, colorSpace))
                        {
                            encoder.WriteJpeg(stream, ToCompressionParameters(parameters));
                        }
                        newPixelData.AddFrame(new MemoryByteBuffer(stream.ToArray()));
                    }
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException("Unable to JPEG encode image", e);
                }
            }

            if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.Rgb)
            {
                newPixelData.PlanarConfiguration = PlanarConfiguration.Interleaved;
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Decodes the image from the specified stream and sets
        /// the data to image.
        /// </summary>
        /// <param name="image">The image, where the data should be set to.
        /// Cannot be null (Nothing in Visual Basic).</param>
        /// <param name="stream">The stream, where the image should be
        /// decoded from. Cannot be null (Nothing in Visual Basic).</param>
        /// <exception cref="System.ArgumentNullException">
        /// 	<para><paramref name="image"/> is null (Nothing in Visual Basic).</para>
        /// 	<para>- or -</para>
        /// 	<para><paramref name="stream"/> is null (Nothing in Visual Basic).</para>
        /// </exception>
        public void Decode(ExtendedImage image, Stream stream)
        {
            Guard.NotNull(image, "image");
            Guard.NotNull(stream, "stream");

            if (UseLegacyLibrary)
            {
                FluxCoreJpegDecoder fluxCoreJpegDecoder = new FluxCoreJpegDecoder(stream);

                DecodedJpeg jpg = fluxCoreJpegDecoder.Decode();

                jpg.Image.ChangeColorSpace(ColorSpace.RGB);

                int pixelWidth = jpg.Image.Width;
                int pixelHeight = jpg.Image.Height;

                byte[] pixels = new byte[pixelWidth * pixelHeight * 4];

                byte[][,] sourcePixels = jpg.Image.Raster;

                for (int y = 0; y < pixelHeight; y++)
                {
                    for (int x = 0; x < pixelWidth; x++)
                    {
                        int offset = (y * pixelWidth + x) * 4;

                        pixels[offset + 0] = sourcePixels[0][x, y];
                        pixels[offset + 1] = sourcePixels[1][x, y];
                        pixels[offset + 2] = sourcePixels[2][x, y];
                        pixels[offset + 3] = (byte)255;

                    }
                }

                //-------

                //
                image.DensityXInt32 = jpg.Image.DensityX;
                image.DensityYInt32 = jpg.Image.DensityY;

                image.SetPixels(pixelWidth, pixelHeight, pixels);
            }
            else
            {
                JpegImage jpg = new JpegImage(stream);

                int pixelWidth = jpg.Width;
                int pixelHeight = jpg.Height;

                byte[] pixels = new byte[pixelWidth * pixelHeight * 4];

                if (!(jpg.Colorspace == Colorspace.RGB && jpg.BitsPerComponent == 8))
                {
                    throw new UnsupportedImageFormatException();
                }

                for (int y = 0; y < pixelHeight; y++)
                {
                    SampleRow row = jpg.GetRow(y);
                    for (int x = 0; x < pixelWidth; x++)
                    {
                        //Sample sample = row.GetAt(x);
                        int offset = (y * pixelWidth + x) * 4;
                        row.GetComponentsAt(x, out pixels[offset + 0], out pixels[offset + 1], out pixels[offset + 2]);
                        //r = (byte)sample[0];
                        //g = (byte)sample[1];
                        //b = (byte)sample[2];  
                        //pixels[offset + 0] = r;
                        //pixels[offset + 1] = g;
                        //pixels[offset + 2] = b;
                        pixels[offset + 3] = (byte)255;
                    }
                }

                image.SetPixels(pixelWidth, pixelHeight, pixels);
            }
        }
Esempio n. 26
0
        private static void testJpegFromBitmap(Bitmap bmp, string jpegFileName)
        {
            using (JpegImage jpeg = new JpegImage(bmp))
            {
                Assert.AreEqual(jpeg.Width, bmp.Width);
                Assert.AreEqual(jpeg.Height, bmp.Height);
                Assert.AreEqual(jpeg.ComponentsPerSample, 3);//Number of components in Bitmap

                using (FileStream output = new FileStream(jpegFileName, FileMode.Create))
                    jpeg.WriteJpeg(output);
            }

            FileAssert.AreEqual(jpegFileName, Path.Combine(m_expectedResults, jpegFileName));
        }