Compression image without very high quality image in c# - c#

I do not need a very high quality image. I will sent this image with socket so I need this image small as possible I need a method to compression image
private void button1_Click_1(object sender, EventArgs e)
{
OpenFileDialog Open_File = new OpenFileDialog();
if (Open_File.ShowDialog() == DialogResult.OK)
{
FileStream fileStream = new FileStream(Open_File.FileName, FileMode.Open, FileAccess.Read);
int length = (int)fileStream.Length;
byte[] buffer = new byte[length];
fileStream.Read(buffer, 0, length);
Image x = byteArrayToImage(buffer);//this image I want to compression
//.............................
}
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}

Motaz,
I worked on an image processing project some while back. The project required the Compression/Decompression of the images. You have two options to do what you want:
1) You can write the algorithm yourself.
2) You can use a library for the Compression/Decompression of the images.
If you want to use a library, you also have to options:
A- You can use open source libraries and articles available on the internet such as the following:
http://www.codeproject.com/Articles/4769/In-Memory-Image-Compression
Or you can use a library such as Aforge
B- You can use commercial library such as leadtools sdk that allows you to increase the compression by just changing the quality factor. Also, for their j2k format you can set the size you want the image to have. For a code sample: see the following links:
For quality factor:
www.leadtools.com/help/leadtools/v175/dh/co/leadtools.codecs~leadtools.codecs.codecspngoptions.html#Example_CS
http://www.leadtools.com/help/leadtools/v175/dh/co/leadtools.codecs~leadtools.codecs.codecsjpegoptions.html#Example_CS
For the setting the J2K file size:
www.leadtools.com/help/leadtools/v175/dh/co/leadtools.codecs~leadtools.codecs.codecsjpeg2000options.html#Example_CS
Using the TargetFileSize property you can set the file size.
In my cause, we decided to go with the commercial toolkit because it gave us more features, better quality and better performance.

Related

Save .jpg image in grayscale using C# [duplicate]

We have a system that provides images in 8-bit grayscale either tiff or jpg formats. However, the component we have to process the images expects image to be in 8-bit jpg format.
When I use .Net to save the tiff images as jpg it convets it to 24-bit image.
Is there a way, hopefully simple and fast, to convert 8-bit grayscale tiff images to equivalent jpg?
I tried and tried just to conclude that I'm sorry: .Net library's Bitmap class DOES NOT save JPEG as 8bpp even when explicitly stated and data is in grayscale.
(note: although stated in some places, JPEG format DOES support 8bpp).
At Convert an image to grayscale you may find code snipet to convert to grayscale any Image.
Using that code, I was able to save a 8bpp grayscale Image instance with '.jpeg' extension, but stating ImageFormat.Gif... that's a cheat...
My findings show as solution an entirely different approach.
The FreeImage library offers powerful APIs, including the feature needed to solve your problem.
It's home page is at http://freeimage.sourceforge.net/faq.html
But, I could not easily compile it in my Win2008 + VS 2010 machine.
One ought to sweat a lot to make it run on modern environments.
Some hints on how to accomplish that are found at http://www.sambeauvois.be/blog/2010/05/freeimage-and-x64-projects-yes-you-can/
Good luck!
Image img = Image.FromFile(filePathOriginal);
Bitmap bmp = ConvertTo8bpp(img);
EncoderParameters parameters = new EncoderParameters();
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8);
bmp.Save(filePathNew, jpgCodec, parameters);
bmp.Dispose();
img.Dispose();
...
private static Bitmap ConvertTo8bpp(Image img) {
var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
using (var gr = Graphics.FromImage(bmp))
{
gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
}
return bmp;
}

JPEG XR to Bitmap in C#

I'm using C#, and need to process Jpeg-XR images. However, these images are presented in form of base64 strings, and need to be converted into Bitmap objects directly. I can write it into a file and convert it, but this significantly affects my running time.
I was wondering if anyone could help me with a sample code, or a hint?
(I already tried Magick.Net, but that didn't work for me, and also doesn't seem to be able to load a JXR image directly).
thanks a lot
JPEG XR is formerly known as HD Photo and Windows Media Photo.
You can use the class WmpBitmapDecoder in System.Windows.Media.Imaging in the WPF library to manipulate .jxr images.
This class Defines a decoder for Microsoft Windows Media Photo encoded images.
The following code convert JXR file to Bmp file:
using System.IO;
using System.Windows.Media.Imaging;
public class JXrLib
{
public static void JxrToBmp(string source, string target)
{
Stream imageStreamSource = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read);
WmpBitmapDecoder decoder = new WmpBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
var encoder = new BmpBitmapEncoder(); ;
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var stream = new FileStream(target, FileMode.Create))
{
encoder.Save(stream);
}
}
}
The code is tested and running fine.
Alternative 2:
If you are interested of using Magick.Net, you can use jxrlib library in https://jxrlib.codeplex.com
Copy the file JXRDecApp.exe and JXREncApp.exe to your bin directory and read from a file on disk that has a .jxr extension.
(you have to compile jxrlib using visual studio)
Code example:
// Read first frame of jxr image
//JXRDecApp.exe ,JXREncApp.exe should be located in the path of binaries
using (MagickImage image = new MagickImage(#"images\myimage1.jxr"))
{
// Save frame as bmp
image.Write("myimage2.bmp");
// even , Save frame as jxr
image.Write("myimage2.jxr");
}

Set image resolution

I have array of image bytes and I would like to set resolution. Original image can be JPEG, PNG, BMP. Output - PNG. I am using ImageMagic to convert image and do some manipulations.
using (var image = this.Convert(originalImage, height, width))
using (var stream = new MemoryStream())
{
image.Quality = 90;
image.Write(stream, MagickFormat.Png);
return stream.GetBuffer();
}
I tryed to modify image.GetExifProfile, but has no success (at least for PNG images).
I can't use any comandline tool (like ImageMagic or ExifTool) here.
There are 3 exiff tags I need to modify
XResolution
YResolution
ResolutionUnit
I can successfully achieve this with bitmap, but it also resource overhead (need to create MemoryStream ...).
I have found some Pdf specification, but it will consume time to make it all work.
Does any can point me to right direction?
Thanks.

Save XAML Image into file in metro apps

i convert a PDF file to BitmapImage in C#. After i manipulate it (resize, rotate) and i want to save it to new PNG or JPEG file but i'm not found how can i make that. I'm developed a windows store apps in C#.
According to this blog post: Save XAML as PNG in a Windows Store App
You should be able to do this using the class BitmapEncoder, the method BitmapSource.CopyPixels will give you the pixels data that BitmapEncoder requires.
Use LibPdf, for PDF to Image conversion
This library converts converts PDF file to an image. Supported image formats are PNG and BMP, but you can easily add more.
Usage example:
using (FileStream file = File.OpenRead(#"..\path\to\pdf\file.pdf")) // in file
{
var bytes = new byte[file.Length];
file.Read(bytes, 0, bytes.Length);
using (var pdf = new LibPdf(bytes))
{
byte[] pngBytes = pdf.GetImage(0,ImageType.PNG); // image type
using (var outFile = File.Create(#"..\path\to\pdf\file.png")) // out file
{
outFile.Write(pngBytes, 0, pngBytes.Length);
}
}
}
ImageMagick, you should also look at this freely available and powerful tool. It's capable of doing what you want and also provides some .NET bindings (as well as bindings to several other languages).

Preserving Image quality

I have a winform C# desktop application.
I have a constant stream of jpegs coming in.
I am comparing the current image with the previous 1.
By using a 3rd party tool - Emgu - I can create a new image that contains just the differences.
I then convert that image to a memory stream and then to a byte array.
In the receiving application I take this byte array and load the image via a memory stream using these bytes.
The trouble is that the image degrades quite a lot.
If I save the image to the hard drive before converting it to a memory stream on the client side the quality of the image is good.
The problem lies when i load it as a memory stream.
I encode it as jpeg.
If I encode it as a PNG before sending to the server the quality is good again.
The trouble with encoding to PNG the size in the byte array shoots up.
What my intention was all along was to reduce the number of bytes I have to upload to improve response time.
Am I doing something wrong or can this not be done?
This is my code:
Bitmap imgContainingDifference
= GetDiffFromEmgu(CurrentJpegImage, PreviousJpegImage);
using (System.IO.MemoryStream msIn = new System.IO.MemoryStream())
{
holding.Save(msIn, System.Drawing.Imaging.ImageFormat.Jpeg);
data = msIn.ToArray();
}
//test here
using (System.IO.MemoryStream msOut = new System.IO.MemoryStream(_data))
{
Bitmap testIMG = (Bitmap)Image.FromStream(msOut);
}
//result is image is poor/degrades
If I do this instead:
using (System.IO.MemoryStream msIn = new System.IO.MemoryStream())
{
holding.Save(msIn, System.Drawing.Imaging.ImageFormat.Png);
data = msIn.ToArray();
}
using (System.IO.MemoryStream msOut = new System.IO.MemoryStream(_data))
{
Bitmap testIMG = (Bitmap)Image.FromStream(msOut);
}
//Image is good BUT the size of the byte array is
//10 times the size of the CurrentFrame right at the start.
This is what the image looks like when using the kid suggestion from :
I have now tried using a encoder from the kind suggestion from #MagnatLU and I also get the same quality of image if I use FreeImage.Net.
You can set JPEG compression level when encoding your file to value that is the best empirical tradeoff between quality and size.

Categories

Resources