public static string SaveSmallestBitmap(Bitmap sourceImage, ScanBitDepth bitDepth, bool highQuality, int quality, out ImageFormat imageFormat) { // Store the image in as little space as possible if (sourceImage.PixelFormat == PixelFormat.Format1bppIndexed) { // Already encoded as 1-bit imageFormat = ImageFormat.Png; return(EncodePng(sourceImage)); } else if (bitDepth == ScanBitDepth.BlackWhite) { // Convert to a 1-bit bitmap before saving to help compression // This is lossless and takes up minimal storage (best of both worlds), so highQuality is irrelevant using (var bitmap = BitmapHelper.CopyToBpp(sourceImage, 1)) { imageFormat = ImageFormat.Png; return(EncodePng(bitmap)); } // Note that if a black and white image comes from native WIA, bitDepth is unknown, // so the image will be png-encoded below instead of using a 1-bit bitmap } else if (highQuality) { // Store as PNG // Lossless, but some images (color/grayscale) take up lots of storage imageFormat = ImageFormat.Png; return(EncodePng(sourceImage)); } else if (Equals(sourceImage.RawFormat, ImageFormat.Jpeg)) { // Store as JPEG // Since the image was originally in JPEG format, PNG is unlikely to have size benefits imageFormat = ImageFormat.Jpeg; return(EncodeJpeg(sourceImage, quality)); } else { // Store as PNG/JPEG depending on which is smaller var pngEncoded = EncodePng(sourceImage); var jpegEncoded = EncodeJpeg(sourceImage, quality); if (new FileInfo(pngEncoded).Length <= new FileInfo(jpegEncoded).Length) { // Probably a black and white image (from native WIA, so bitDepth is unknown), which PNG compresses well vs. JPEG File.Delete(jpegEncoded); imageFormat = ImageFormat.Png; return(pngEncoded); } else { // Probably a color or grayscale image, which JPEG compresses well vs. PNG File.Delete(pngEncoded); imageFormat = ImageFormat.Jpeg; return(jpegEncoded); } } }
public bool IsBlank(Bitmap bitmap, int whiteThresholdNorm, int coverageThresholdNorm) { if (bitmap.PixelFormat == PixelFormat.Format1bppIndexed) { using (var bitmap2 = BitmapHelper.CopyToBpp(bitmap, 8)) { return(IsBlankRgb(bitmap2, whiteThresholdNorm, coverageThresholdNorm)); } } return(bitmap.PixelFormat == PixelFormat.Format24bppRgb && IsBlankRgb(bitmap, whiteThresholdNorm, coverageThresholdNorm)); }
public static void GetSmallestBitmap(Bitmap sourceImage, ScanBitDepth bitDepth, bool highQuality, out Bitmap bitmap, out MemoryStream encodedBitmap, out ImageFormat imageFormat) { // Defaults for out arguments bitmap = null; encodedBitmap = null; imageFormat = ImageFormat.Png; // Store the image in as little space as possible if (bitDepth == ScanBitDepth.BlackWhite) { // Store as a 1-bit bitmap // This is lossless and takes up minimal storage (best of both worlds), so highQuality is irrelevant bitmap = (Bitmap)BitmapHelper.CopyToBpp(sourceImage, 1).Clone(); // Note that if a black and white image comes from native WIA, bitDepth is unknown, // so the image will be png-encoded below instead of using a 1-bit bitmap } else if (highQuality) { // Store as PNG // Lossless, but some images (color/grayscale) take up lots of storage encodedBitmap = EncodeBitmap(sourceImage, ImageFormat.Png); } else { // Store as PNG/JPEG depending on which is smaller var pngEncoded = EncodeBitmap(sourceImage, ImageFormat.Png); var jpegEncoded = EncodeBitmap(sourceImage, ImageFormat.Jpeg); if (pngEncoded.Length <= jpegEncoded.Length) { // Probably a black and white image (from native WIA, so bitDepth is unknown), which PNG compresses well vs. JPEG encodedBitmap = pngEncoded; jpegEncoded.Dispose(); } else { // Probably a color or grayscale image, which JPEG compresses well vs. PNG encodedBitmap = jpegEncoded; pngEncoded.Dispose(); imageFormat = ImageFormat.Jpeg; } } }