public FileBasedScannedImage(Bitmap img, ScanBitDepth bitDepth, bool highQuality) { Bitmap baseImage; MemoryStream baseImageEncoded; ScannedImageHelper.GetSmallestBitmap(img, bitDepth, highQuality, out baseImage, out baseImageEncoded, out baseImageFileFormat); baseImageFileName = (_recoveryFileNumber++).ToString("D5", CultureInfo.InvariantCulture) + GetExtension(baseImageFileFormat); baseImageFilePath = Path.Combine(RecoveryFolder.FullName, baseImageFileName); if (baseImage != null) { // TODO: If I'm stuck using PNG anyway, then don't treat B&W specially baseImage.Save(baseImageFilePath, baseImageFileFormat); baseImage.Dispose(); } else { Debug.Assert(baseImageEncoded != null); using (var fs = new FileStream(baseImageFilePath, FileMode.CreateNew)) { baseImageEncoded.Seek(0, SeekOrigin.Begin); baseImageEncoded.CopyTo(fs); } baseImageEncoded.Dispose(); } _recoveryIndexManager.Index.Images.Add(new RecoveryIndexImage { FileName = baseImageFileName, BitDepth = bitDepth, HighQuality = highQuality, TransformList = transformList }); _recoveryIndexManager.Save(); }
public ScannedImage(Bitmap img, ScanBitDepth bitDepth, bool highQuality, int quality) { Bitmap baseImage; MemoryStream baseImageEncoded; ImageFormat baseImageFileFormat; ScannedImageHelper.GetSmallestBitmap(img, bitDepth, highQuality, quality, out baseImage, out baseImageEncoded, out baseImageFileFormat); transformList = new List<Transform>(); recoveryImage = RecoveryImage.CreateNew(baseImageFileFormat, bitDepth, highQuality, transformList); if (baseImage != null) { baseImage.Save(recoveryImage.FilePath, recoveryImage.FileFormat); baseImage.Dispose(); } else { Debug.Assert(baseImageEncoded != null); using (var fs = new FileStream(recoveryImage.FilePath, FileMode.CreateNew)) { baseImageEncoded.Seek(0, SeekOrigin.Begin); baseImageEncoded.CopyTo(fs); } baseImageEncoded.Dispose(); } recoveryImage.Save(); }
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 ScannedImage(Bitmap img, ScanBitDepth bitDepth, bool highQuality, int quality) { var tempFilePath = ScannedImageHelper.SaveSmallestBitmap(img, bitDepth, highQuality, quality, out var fileFormat); transformList = new List <Transform>(); recoveryImage = RecoveryImage.CreateNew(fileFormat, bitDepth, highQuality, transformList); File.Move(tempFilePath, recoveryImage.FilePath); recoveryImage.Save(); }
public ScannedImage(Bitmap img, ScanBitDepth bitDepth, bool highQuality, int quality) { ImageFormat fileFormat; string tempFilePath = ScannedImageHelper.SaveSmallestBitmap(img, bitDepth, highQuality, quality, out fileFormat); transformList = new List<Transform>(); recoveryImage = RecoveryImage.CreateNew(fileFormat, bitDepth, highQuality, transformList); File.Move(tempFilePath, recoveryImage.FilePath); recoveryImage.Save(); }
private RecoveryImage(ImageFormat fileFormat, ScanBitDepth bitDepth, bool highQuality, List <Transform> transformList) { FileFormat = fileFormat; FileName = GetNextFileName() + GetExtension(FileFormat); FilePath = Path.Combine(RecoveryFolder.FullName, FileName); IndexImage = new RecoveryIndexImage { FileName = FileName, BitDepth = bitDepth, HighQuality = highQuality, TransformList = transformList }; }
private RecoveryImage(ImageFormat fileFormat, ScanBitDepth bitDepth, bool highQuality, List <Transform> transformList) { FileFormat = fileFormat; FileName = (_recoveryFileNumber++).ToString("D5", CultureInfo.InvariantCulture) + GetExtension(FileFormat); FilePath = Path.Combine(RecoveryFolder.FullName, FileName); IndexImage = new RecoveryIndexImage { FileName = FileName, BitDepth = bitDepth, HighQuality = highQuality, TransformList = transformList }; }
private ScannedImage TransferImage(WiaBackgroundEventLoop eventLoop, int pageNumber, out bool cancel) { try { // TODO: Use the NoUI flag uniformly var transfer = ScanParams.NoUI ? new ConsoleWiaTransfer() : wiaTransfer; using (var stream = transfer.Transfer(pageNumber, eventLoop, WiaApi.Formats.BMP)) { if (stream == null) { cancel = true; return(null); } cancel = false; using (Image output = Image.FromStream(stream)) { using (var result = ScannedImageHelper.PostProcessStep1(output, ScanProfile)) { if (blankDetector.ExcludePage(result, ScanProfile)) { return(null); } ScanBitDepth bitDepth = ScanProfile.UseNativeUI ? ScanBitDepth.C24Bit : ScanProfile.BitDepth; var image = new ScannedImage(result, bitDepth, ScanProfile.MaxQuality, ScanProfile.Quality); image.SetThumbnail(thumbnailRenderer.RenderThumbnail(result)); ScannedImageHelper.PostProcessStep2(image, ScanProfile, pageNumber); return(image); } } } } catch (NoPagesException) { if (ScanProfile.PaperSource != ScanSource.Glass && pageNumber == 1) { // No pages were in the feeder, so show the user an error throw new NoPagesException(); } // At least one page was scanned but now the feeder is empty, so exit normally cancel = true; return(null); } catch (ScanDriverException) { throw; } catch (Exception e) { throw new ScanDriverUnknownException(e); } }
private IScannedImage TransferImage(WiaBackgroundEventLoop eventLoop, int pageNumber) { try { using (var stream = wiaTransfer.Transfer(pageNumber, eventLoop, WiaApi.Formats.BMP)) { if (stream == null) { // User cancelled return(null); } using (Image output = Image.FromStream(stream)) { double scaleFactor = 1; if (!ScanSettings.UseNativeUI) { scaleFactor = ScanSettings.AfterScanScale.ToIntScaleFactor(); } using (var result = ImageScaleHelper.ScaleImage(output, scaleFactor)) { ScanBitDepth bitDepth = ScanSettings.UseNativeUI ? ScanBitDepth.C24Bit : ScanSettings.BitDepth; return(scannedImageFactory.Create(result, bitDepth, ScanSettings.MaxQuality)); } } } } catch (COMException e) { if ((uint)e.ErrorCode == WiaApi.Errors.OUT_OF_PAPER) { if (ScanSettings.PaperSource != ScanSource.Glass && pageNumber == 1) { throw new NoPagesException(); } return(null); } else if ((uint)e.ErrorCode == WiaApi.Errors.OFFLINE) { throw new DeviceOfflineException(); } else { throw new ScanDriverUnknownException(e); } } }
private async Task <(ScannedImage, bool)> TransferImage(WiaBackgroundEventLoop eventLoop, int pageNumber) { return(await Task.Factory.StartNew(() => { try { ChaosMonkey.MaybeError(0, new COMException("Fail", -2147467259)); using (var stream = DoTransfer(pageNumber, eventLoop, WiaApi.Formats.BMP)) { if (stream == null) { return (null, true); } using (Image output = Image.FromStream(stream)) { using (var result = scannedImageHelper.PostProcessStep1(output, ScanProfile)) { if (blankDetector.ExcludePage(result, ScanProfile)) { return (null, false); } ScanBitDepth bitDepth = ScanProfile.UseNativeUI ? ScanBitDepth.C24Bit : ScanProfile.BitDepth; var image = new ScannedImage(result, bitDepth, ScanProfile.MaxQuality, ScanProfile.Quality); scannedImageHelper.PostProcessStep2(image, result, ScanProfile, ScanParams, pageNumber); string tempPath = scannedImageHelper.SaveForBackgroundOcr(result, ScanParams); scannedImageHelper.RunBackgroundOcr(image, ScanParams, tempPath); return (image, false); } } } } catch (NoPagesException) { if (ScanProfile.PaperSource != ScanSource.Glass && pageNumber == 1) { // No pages were in the feeder, so show the user an error throw new NoPagesException(); } // At least one page was scanned but now the feeder is empty, so exit normally return (null, true); } }, TaskCreationOptions.LongRunning)); }
private void ProduceImage(ScannedImageSource.Concrete source, Image output, ref int pageNumber) { var results = new[] { scannedImageHelper.PostProcessStep1(output, ScanProfile) }; if (ScanProfile.DivideScanIntoTwoPages) { var result = results[0]; // Should probably detect portrait vs landscape and split appropriately but this is the // main use case. var halfHeight = result.Height / 2; var firstRect = new Rectangle(0, 0, result.Width, halfHeight); var secondRect = new Rectangle(0, halfHeight, result.Width, halfHeight); var firstPage = result.Clone(secondRect, result.PixelFormat); firstPage.RotateFlip(RotateFlipType.Rotate90FlipNone); var secondPage = result.Clone(firstRect, result.PixelFormat); secondPage.RotateFlip(RotateFlipType.Rotate90FlipNone); results = new[] { firstPage, secondPage }; result.Dispose(); } foreach (var result in results) { if (blankDetector.ExcludePage(result, ScanProfile)) { continue; } ScanBitDepth bitDepth = ScanProfile.UseNativeUI ? ScanBitDepth.C24Bit : ScanProfile.BitDepth; var image = new ScannedImage(result, bitDepth, ScanProfile.MaxQuality, ScanProfile.Quality); scannedImageHelper.PostProcessStep2(image, result, ScanProfile, ScanParams, pageNumber); string tempPath = scannedImageHelper.SaveForBackgroundOcr(result, ScanParams); result.Dispose(); scannedImageHelper.RunBackgroundOcr(image, ScanParams, tempPath); source.Put(image); pageNumber++; InitNextPageProgress(pageNumber); } }
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; } } }
private void ProduceImage(ScannedImageSource.Concrete source, Image output, ref int pageNumber) { using (var result = scannedImageHelper.PostProcessStep1(output, ScanProfile)) { if (blankDetector.ExcludePage(result, ScanProfile)) { return; } ScanBitDepth bitDepth = ScanProfile.UseNativeUI ? ScanBitDepth.C24Bit : ScanProfile.BitDepth; var image = new ScannedImage(result, bitDepth, ScanProfile.MaxQuality, ScanProfile.Quality); scannedImageHelper.PostProcessStep2(image, result, ScanProfile, ScanParams, pageNumber); string tempPath = scannedImageHelper.SaveForBackgroundOcr(result, ScanParams); scannedImageHelper.RunBackgroundOcr(image, ScanParams, tempPath); source.Put(image); pageNumber++; InitNextPageProgress(pageNumber); } }
public ScannedImage(String imgBase64, ScanBitDepth bitDepth, bool highQuality) { using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(imgBase64))) using (Image image = Image.FromStream(stream)) { this.bitDepth = bitDepth; Thumbnail = ThumbnailHelper.GetThumbnail(new Bitmap(image)); ScannedImageHelper.GetSmallestBitmap(new Bitmap(image), bitDepth, highQuality, out baseImage, out baseImageEncoded, out baseImageFileFormat); } ////Convertir String a Imagen //// Convert Base64 String to byte[] //byte[] imageBytes = Convert.FromBase64String(imgBase64); //// Convert byte[] to Image //using (var ms = new MemoryStream(imageBytes, 0, imageBytes.Length)) //{ // Image image = Image.FromStream(ms, true); // // // //} }
public IScannedImage Create(Bitmap img, ScanBitDepth bitDepth, bool highQuality) { return(new FileBasedScannedImage(img, bitDepth, highQuality)); }
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 (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 static RecoveryImage CreateNew(ImageFormat fileFormat, ScanBitDepth bitDepth, bool highQuality, List<Transform> transformList) { return new RecoveryImage(fileFormat, bitDepth, highQuality, transformList); }
private RecoveryImage(ImageFormat fileFormat, ScanBitDepth bitDepth, bool highQuality, List<Transform> transformList) { FileFormat = fileFormat; FileName = (_recoveryFileNumber++).ToString("D5", CultureInfo.InvariantCulture) + GetExtension(FileFormat); FilePath = Path.Combine(RecoveryFolder.FullName, FileName); IndexImage = new RecoveryIndexImage { FileName = FileName, BitDepth = bitDepth, HighQuality = highQuality, TransformList = transformList }; }
public static RecoveryImage CreateNew(ImageFormat fileFormat, ScanBitDepth bitDepth, bool highQuality, List <Transform> transformList) { return(new RecoveryImage(fileFormat, bitDepth, highQuality, transformList)); }
public IScannedImage Create(Bitmap img, ScanBitDepth bitDepth, bool highQuality, int quality) { return new FileBasedScannedImage(img, bitDepth, highQuality, quality); }
public ScannedImage(Bitmap img, ScanBitDepth bitDepth, bool highQuality) { this.bitDepth = bitDepth; ScannedImageHelper.GetSmallestBitmap(img, bitDepth, highQuality, out baseImage, out baseImageEncoded, out baseImageFileFormat); }
public ScannedImage(Bitmap img, ScanBitDepth bitDepth, bool highQuality) { this.bitDepth = bitDepth; Thumbnail = ThumbnailHelper.GetThumbnail(img); ScannedImageHelper.GetSmallestBitmap(img, bitDepth, highQuality, out baseImage, out baseImageEncoded, out baseImageFileFormat); }
public IScannedImage Create(Bitmap img, ScanBitDepth bitDepth, bool highQuality) { return new ScannedImage(img, bitDepth, highQuality); }