I have a screen shot I take in my mobile app. The screen shot takes about 32 KB when saved as a png on a disk.
I am sending these to a central SQL Server and 32 KB is too big for that amount of times I will need to store that screen shot (approx 2500 times a day).
Is there any kind of trickery that I can do to get it to save smaller?
Here is the code I am using now to take it from Bitmap
to bytes (to send to the server for storage):
MemoryStream stream = new MemoryStream();
_signatureImage.Save(stream, ImageFormat.Png);
return stream.ToArray();
_signatureImage
is a Bitmap
and is the screenshot in question.
Here is an example of the screen shot I am saving:
Things that pop to mind (but I don't know how to do them):
Note, this all has to be done programatically, and cannot take very long, so complex image manipulations are out.
Thanks for any help.
One of the simplest ways to resize an image in the HTML is using the height and width attributes on the img tag. These values specify the height and width of the image element. The values are set in px i.e. CSS pixels.
How to reduce the image size in KB/MB? To reduce the image size in KB or MB online, first upload it to ResizePixel's website. Enter a desired file size and select the corresponding unit of measurement (KB or MB). Then proceed to Download page to get the image file.
private static Image ResizeImage(int newSize, Image originalImage)
{
if (originalImage.Width <= newSize)
newSize = originalImage.Width;
var newHeight = originalImage.Height * newSize / originalImage.Width;
if (newHeight > newSize)
{
// Resize with height instead
newSize = originalImage.Width * newSize / originalImage.Height;
newHeight = newSize;
}
return originalImage.GetThumbnailImage(newSize, newHeight, null, IntPtr.Zero);
}
This should work with your Bitmap object Type and resize the Height or Width, depending on which is appropriate for your image dimensions. It will also maintain scale.
EDIT:
You could create a new Bitmap object and resize your original image into that Bitmap object.
Bitmap b = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, newWidth, newHeight);
g.Dispose();
return (Image)b;
I don't have the Compact Framework installed, but it seems that this should work for you.
If color depth is not an issue, you might change it to black and white, or 16 color mode. There should be a significant savings over png's 24-bpp (or 32-bpp with alpha) storage requirements. The other thing to think about is saving it as a .gif file in 256 color mode.
As you're saving signature data, I'd think changing the dimensions of the image would be a bad idea. You might also consider applying a lossless compression like zip, but that is likely more computationally intensive than you require.
Change the color palette to a lower color depth. Take a look at this question (well look at the answert really) which shows converting to 1bpp. You could go to 8bpp instead of 1bpp and have significant size savings. The mechanism for conversion will be the same as what is shown.
EDIT
Thinking out of the box, you might also consider just sending the data points from the upper part of the screen and the signature vector, and have the server recreate the screen for you. If size really is a big issue, I'd probably investigate that.
EDIT 2
If simply resizing the image is a reasonable solution (you'll obviously lose data in doing so) then you can use the Imaging namespace in the SDF to create a thumbnail as Alex explains here.
If monochrome image is acceptable, you can try TIFF G4 (lossless compression). TIFF G4 is known for being very effective in file size to store black and white image. Unfortunately I dont have any info available on how it compares to PNG, but worth investigating into it.
Here is the info and example on how to do it in C#
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With