C# How can I watermark a jpeg image? - c#

Using C# how would I watermark an jpeg image that I'm reading into a memory stream and saving to a byte array?
using (MemoryStream imageStream = new MemoryStream())
{
pbPreview.Image.Save(imageStream, ImageFormat.Jpeg);
photoBytes = imageStream.ToArray();
}
Thank you

Please take a look: Watermark Creator and Creating a Watermarked Photograph with GDI+ for .NET
A more detailed explanation here: Build a simple watermarking utility in C#

Related

How convert Image to png with imagemagik lib in C#?

I've write a aws Lambda to convert my images.
The process of the lambda function is to take input images of any format and in the case of non-png images, convert them to jpeg otherwise add some data and convert it to png by adding transparency. Finally save the generated images on s3.
I write a function in C# using a imagemagick library in .Net Core.
I've a problem with png conversion. The result image have a dashed border!
This is my method to PNG convert.
private MemoryStream ConvertToPNG(MemoryStream inputStream)
{
MemoryStream outputStream = new MemoryStream();
inputStream.Position = 0;
using (MagickImage image = new MagickImage())
{
image.Read(inputStream);
image.Quality = 90;
image.TransformColorSpace(ColorProfile.SRGB, ColorProfile.AdobeRGB1998);
image.Settings.Compression = CompressionMethod.NoCompression;
image.Format = MagickFormat.Png64;
image.Write(outputStream);
}
return outputStream;
}
I tried with another stack, using Pillow library in py and work, generated image is great. Unfortunately I am forced to use C # and .Net for obvious reasons.
Has anyone ever had this problem?
Thanks everyone for the contribution.

HttpPostedFileBase to Resized Image

I have the following line of code which takes my HttpPostedFileBase and converts it to an image.
I have messed around with Encoder Parameteres to try and resize the image but can't seem to do this.
What is the best way to resize the image to 250x250?
I would also prefer it to take the middle of the image as 250x250 rectangle rather than somewhere random.
What is the most space efficent way to convert and save the image as it will be going in the database?
Please note that model.Image is of type HttpPostedFileBase.
var image = Image.FromStream(model.Image.InputStream, true, true);
ImageCodecInfo jpgInfo = ImageCodecInfo.GetImageEncoders()
.Where(codecInfo => codecInfo.MimeType == "image/jpeg").First();
using (EncoderParameters encParams = new EncoderParameters(1))
{
encParams.Param[0] = new EncoderParameter(Encoder.Quality, (long)50);
//quality should be in the range [0..100]
using (var ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, ImageFormat.Jpeg);
byte[] imageBytes = ms.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
image64 = base64String;
}
}
The best way is to use an established library like ImageResizer; that way, you avoid re-inventing the wheel. If you are concerned about space efficiency (file size), use the JPEG format with maximum compression. Note that using JPEG's lossy encoding will drastically reduce image quality. If you want to use a lossless encoding, try PNG. Compressing PNG images is quite difficult in .NET, in my experience. I searched in vain awhile back for a single library that would do it and all I found were thick-client Windows applications.

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.

Convert bitmap from 16bpp to 8bpp in C#

I have a Bitmap with 16bpp. I want to convert that image in my ASP.NET side in a 8bpp image.
I tried a lot of options which I found in the internet but nothing works for me.
I also tried that way: C# Converting 32bpp image to 8bpp
But if I want to save the file, I get the following error:
Exception Details: System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.
Line 278: System.Drawing.Image img2 = Convert(bm_resize);//byteArrayToImage(gray);
Line 279:
Line 280: img2.Save(helper+"grey2.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
Line 281: }
Line 282:
Is there any correct way for my problem?
Full Code:
System.Drawing.Image img2 = Convert(bm_resize);
img2.Save(path+"test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
public static System.Drawing.Image Convert(Bitmap oldbmp)
{
using (MemoryStream ms = new MemoryStream())
{
oldbmp.Save(ms, ImageFormat.Gif);
ms.Position = 0;
return System.Drawing.Image.FromStream(ms);
}
}
The problem is caused by disposing the memory stream before the image is saved.
I believe GDI+ requires the memory stream to persist while you are still working with an Image created from the memory stream.
See the Microsoft Support article.
I use a little helper function to create 1 bpp monochrome bitmaps in .NET. Check out this link, it also works great for 8 bpp
http://www.wischik.com/lu/programmer/1bpp.html
hope this could help!
AForge.Net has a good collection of free (under Lesser GPL License) routines for such changes and a lot more. Conversion of 16bpp to 8bpp is as simple as this.

Convert System.Windows.Media.ImageSource to System.Drawing.Bitmap

How can I convert a System.Windows.Media.ImageSource to a System.Drawing.Bitmap in C#?
its older OP, but still it can come handy for some other people, as it took some time to find cleaner solution without dll interop or clipboard hacks.
this worked for me, you can use pngencoder to cut the image size before saving to file or rtf stream
private System.Drawing.Image ImageWpfToGDI(System.Windows.Media.ImageSource image) {
MemoryStream ms = new MemoryStream();
var encoder = new System.Windows.Media.Imaging.BmpBitmapEncoder();
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(image as System.Windows.Media.Imaging.BitmapSource));
encoder.Save(ms);
ms.Flush();
return System.Drawing.Image.FromStream(ms);
}
Please see HOW TO USE IMAGESOURCE (NO HANDLER) IN WINFORMS AS SYSTEM.DRAWING.BITMAP (HBITMAP):
How to easily convert WinForms
System.Drawing.Bitmap into WPF
ImageSource you learned from this
article. Today, I'll explain how to do
it contrary. Actually, all he have to
do is to extract handler from
BitmapSource, however, such approach
is not supported, thus the only thing
we can do is just copy pixels of
BitmapSource (or BitmapFrame) into
byte array and then copy them into the
pointer of HBitmap.

Categories

Resources