I'm using NTwain to scan documents into memory and I have it all working except for one part: When trying to set the size of the page to scan, it scans the entire width and height, rather than just the specified size.
I went and examined the details of NTwain's capabilities on the current source, and found the the ICapSupportedSizes was not supported for any action.
Here's how I'm setting the capabilities (this is on an open, valid source)
_twain.CurrentSource.Capabilities.ICapXResolution.SetValue(new TWFix32() { Whole = 600 });
_twain.CurrentSource.Capabilities.ICapYResolution.SetValue(new TWFix32() { Whole = 600 });
_twain.CurrentSource.Capabilities.ICapPixelType.SetValue(PixelType.BlackWhite);
_twain.CurrentSource.Capabilities.ICapSupportedSizes.SetValue(SupportedSize.USLegal);
_twain.CurrentSource.Capabilities.CapDuplexEnabled.SetValue(BoolType.False);
UPDATE:
I've found out that none of the settings are actually working. I set it as black and white, even if it shows black and white in the settings, it displays in color. Doesn't matter what DPI I set it at either as it defaults to 300 no matter what. I've updated it to grab out the source and use that to change the settings and call Enable, but it still doesn't work.
Any help is appreciated.
Thanks!
Enviornment Information
.NET Framework 4.6.1
Win Forms
C#
NTwain
Scanner: Canon Flatbed Scanner Unit 102
You will need to use the DGImage.ImageLayout property to set the page size in a generally-supported way.
For example:
var ds = _twain.CurrentSource;
ds.Capabilities.ICapUnits.SetValue(Unit.Inches);
ds.DGImage.ImageLayout.Get(out TWImageLayout imageLayout);
imageLayout.Frame = new TWFrame
{
Left = 0,
Right = pageWidthInInches,
Top = 0,
Bottom = pageHeightInInches
};
ds.DGImage.ImageLayout.Set(imageLayout);
Related
I'm working on a small personal application that should read some text (2 sentences at most) from a really simple Android screenshot. The text is always the same size, same font, and in approx. the same location. The background is very plain, usually a few shades of 1 color (think like bright orange fading into a little darker orange). I'm trying to figure out what would be the best way (and most importantly, the fastest way) to do this.
My first attempt involved the IronOcr C# library, and to be fair, it worked quite well! But I've noticed a few issues with it:
It's not 100% accurate
Despite having a community/trial version, it sometimes throws exceptions telling you to get a license
It takes ~400ms to read a ~600x300 pixel image, which in the case of my simple image, I consider to be rather long
As strange as it sounds, I have a feeling that libraries like IronOcr and Tesseract may just be too advanced for my needs. To improve speeds I have even written a piece of code to "treshold" my image first, making it completely black and white.
My current IronOcr settings look like this:
ImageReader = new AdvancedOcr()
{
CleanBackgroundNoise = false,
EnhanceContrast = false,
EnhanceResolution = false,
Strategy = AdvancedOcr.OcrStrategy.Fast,
ColorSpace = AdvancedOcr.OcrColorSpace.GrayScale,
DetectWhiteTextOnDarkBackgrounds = true,
InputImageType = AdvancedOcr.InputTypes.Snippet,
RotateAndStraighten = false,
ReadBarCodes = false,
ColorDepth = 1
};
And I could totally live with the results I've been getting using IronOcr, but the licensing exceptions ruin it. I also don't have $399 USD to spend on a private hobby project that won't even leave my own PC :(
But my main goal with this question is to find a better, faster or more efficient way to do this. It doesn't necessarily have to be an existing library, I'd be more than willing to make my own kind of letter-detection code that would work (only?) for screenshots like mine if someone can point me in the right direction.
I have researched about this topic and the best solution which I could find is Azure cognitive services. You can use Computer vision API to read text from an image. Here is the complete document.
How fast does it have to be?
If you are using C# I recommend the Google Cloud Vision API. You pay per request but the first 1000 per month are free (check pricing here). However, it does require a web request but I find it to be very quick
using Google.Cloud.Vision.V1;
using System;
namespace GoogleCloudSamples
{
public class QuickStart
{
public static void Main(string[] args)
{
// Instantiates a client
var client = ImageAnnotatorClient.Create();
// Load the image file into memory
var image = Image.FromFile("wakeupcat.jpg");
// Performs label detection on the image file
var response = client.DetectText(image);
foreach (var annotation in response)
{
if (annotation.Description != null)
Console.WriteLine(annotation.Description);
}
}
}
}
I find it works well for pictures and scanned documents so it should work perfectly for your situation. The SDK is also available in other languages too like Java, Python, and Node
I'm trying to take a full screen screenshot of my page by using this code:
public void OpenEyesForVisualTesting(string testName) {
this.seleniumDriver.Driver = this.eyes.Open(this.seleniumDriver.Driver, "Zinc", testName);
}
public void CheckScreenForVisualTesting() {
this.eyes.Check("Zinc", Applitools.Selenium.Target.Window().Fully());
}
public void CloseEyes() {
this.eyes.close();
}
but instead I just get a half a page of the screenshot, I tried to contact Applitools but they just told me to replace eyes.checkwindow() to eyes.Check("tag", Target.Window().Fully()); which still didn't work.
If anyone can help me that would be great.
I work for Applitools and sorry for your troubles. Maybe you did not see our replies or they went to your spam folder. You need to set ForceFullPageScreenshot = true and StitchMode = StitchModes.CSS in order to capture a full page screenshot.
The below code example is everything you'd need to do in order to capture a full page image. Also, please make sure your .Net Eyes.Sdk version is >= 2.6.0 and Eyes.Selenium >= 2.5.0.
If you have any further questions or still encountering issues with this please feel free to email me directly. Thanks.
var eyes = new Eyes();
eyes.ApiKey = "your-api-key";
eyes.ForceFullPageScreenshot = true;
eyes.StitchMode = StitchModes.CSS;
eyes.Open(driver, "Zinc", testName, new Size(800, 600)); //last parameter is your viewport size IF testing on a browser. Do not set if testing on a mobile devices.
eyes.CheckWindow("Zinc");
//or new Fluet API method
eyes.Check("Zinc", Applitools.Selenium.Target.Window().Fully();
eyes.Close();
Use extent Reporting library, in that you can take screen shot as well as an interactive report on pass and fail cases.
here is the link how it works:
http://www.softwaretestingmaterial.com/generate-extent-reports/
If you want to take complete page Screenshot/ Particular element with Applitools. You can use lines of code:-
Full Screenshot
eyes.setHideScrollbars(false);
eyes.setStitchMode(StitchMode.CSS);
eyes.setForceFullPageScreenshot(true);
eyes.checkWindow();
Take screenshot for particular element
WebElement Button = driver.findElement(By.xpath("//button[#id='login-btn']"));
eyes.setHideScrollbars(false);
eyes.setStitchMode(StitchMode.CSS);
eyes.open(driver, projectName, testName);
eyes.setMatchLevel(MatchLevel.EXACT);
eyes.checkElement(Button );
(I am from Applitools.)
When setting forcefullpagescreenshoot to true, applitools will try to scroll the HTML element in the page, if the HTML is not the scrollable element then you will need to set it yourself:
eyes.Check(Target.Window().ScrollRootElement(selector))
In Firefox, you can see a scroll tag near elements that are scrollable.
I have run into a problem that seems to have little information on the web and has been giving me trouble the past two days. When I print to an 8.5 x 11" piece of paper, the output is correct on all printers. When I print to 11 x 17", the output is correct on all virtual (doPDF7, XPS Document Writer) printers. The output on an actual physical printer (Xerox WorkCentre 7535) only renders, from the top-left corner, 8.5 x 11" worth of my control onto a 11 x 17" piece of paper. My control is properly sized (dimension of the 11 x 17") it just doesn't get completely rendered.
I have a Print Preview control implemented where the user can select a printer (PrintQueue) and the settings (PrintCapabilities) for their selected printer. Changing these settings will show up during run time so the user knows exactly what they are printing.
When the user then wants to print their document, I prepare the selected PrintQueue by merging the ticket (their selections in the print preview) with the PrintQueue.CurrentJobSettings.CurrentPrintTicket:
public void Prepare(PrintTicket ticketToMerge)
{
// _printer is the PrintQueue
// I've also tried to merge with UserPrintTicket, DefaultPrintTicket, and created a PrintTicket using XPS Document Writer printer default print ticket
System.Printing.ValidationResult result = _printer.MergeAndValidatePrintTicket(_printer.CurrentJobSettings.CurrentPrintTicket, ticketToMerge);
_printer.CurrentJobSettings.CurrentPrintTicket = result.ValidatedPrintTicket;
_printer.Commit();
// _printer.Refresh(); // This doesn't help it seems
}
then I call to print my DocumentPaginator:
public void Print(DocumentPaginator paginator)
{
var writer = PrintQueue.CreateXpsDocumentWriter(_printer);
writer.Write(paginator, _printer.CurrentJobSettings.CurrentPrintTicket);
}
and the actual printer calls DocumentPaginator.GetPage:
public override DocumentPage GetPage(int pageNumber)
{
var view = new PrintingContent
{
// Create my control and make it the biggest size it can be without
// going into the margins
// Subtract the margins since they can't be printed in, these come from
// _printerCapabilities.PageImageableArea
Width = this.PageSize.Width - this.Margin.Left - this.Margin.Right,
Height = this.PageSize.Height - this.Margin.Top - this.Margin.Bottom,
// This might be a problem since the print preview control
// is also using "this" but haven't found any evidence to conclude this thought
DataContext = this
};
view.Measure(new Size(view.Width, view.Height));
view.Arrange(new Rect(new Point(), new Size(view.Width, view.Height)));
view.UpdateLayout();
var dg = UItilities.FindVisualChildren<DataGrid>(view).First();
// dg.ItemsSource = (File as ParameterCollectionShell).GetParametersByPage(pageNumber)
// This didn't work so I tried giving the datagrid a new instance of List - this might be causing problems?
var parameters = new List<ParameterViewModel>((File as ParameterCollectionShell).GetParametersByPage(pageNumber));
dg.ItemsSource = parameters;
// Doesn't seem to help
// view.Measure(new Size(view.Width, view.Height));
// view.Arrange(new Rect(new Point(), new Size(view.Width, view.Height)));
view.UpdateLayout();
//return new DocumentPage(view,
// this.PageSize,
// new Rect(new Point(), new Size(view.Width, view.Height)),
// new Rect(new Point(this.Margin.Left, this.Margin.Top),
// new Size(view.Width, view.Height)));
return new DocumentPage(view);
}
Of course I have debugged this and checked sizes to make sure they are what they are supposed to be. Everything works printing to an .xps document or .pdf; but why doesn't it work when being sent to a physical printer?
For what it's worth, there is a DataGrid in my control and I had trouble with *-size spacing columns in the past, but they are all fixed width so I'm not sure if its related or not.
It turns out that it must have been a printer driver issue. I re-installed the driver for the same printer and after doing so everything worked correctly.
I got in direct contact with Xerox's firmware team for the specific printer and they let me know that there was firmware updates for the printer and that it could be serviced to hopefully fix it. They couldn't pin point exactly what the issue is, but the issue is now in their bug system.
When in doubt, re-install a printers driver and try printing again when you're having rendering problems. I'm not sure what invokes this bad behavior but printing to any other printer worked correctly; that's how I narrowed it down to a driver issue.
I am not an experienced programmer, just need to add a DICOM viewer to my VS2010 project. I can display the image in Windows Forms, however can't figure out how to change the window center and width. Here is my script:
DicomImage image = new DicomImage(_filename);
int maxV = image.NumberOfFrames;
sbSlice.Maximum = maxV - 1;
image.WindowCenter = 7.0;
double wc = image.WindowCenter;
double ww = image.WindowWidth;
Image result = image.RenderImage(0);
DisplayImage(result);
It did not work. I don't know if this is the right approach.
The DicomImage class was not created with the intention of it being used to implement an image viewer. It was created to render preview images in the DICOM Dump utility and to test the image compression/decompression codecs. Maybe it was a mistake to include it in the library at all?
It is difficult for me to find fault in the code as being buggy when it is being used for something far beyond its intended functionality.
That said, I have taken some time to modify the code so that the WindowCenter/WindowWidth properties apply to the rendered image. You can find these modifications in the Git repo.
var img = new DicomImage(fileName);
img.WindowCenter = 2048.0;
img.WindowWidth = 4096.0;
DisplayImage(img.RenderImage(0));
I looked at the code and it looked extremely buggy. https://github.com/rcd/fo-dicom/blob/master/DICOM/Imaging/DicomImage.cs
In the current buggy implementation setting the WindowCenter or WindowWidth properties has no effect unless Dataset.Get(DicomTag.PhotometricInterpretation) is either Monochrome1 or Monochrome2 during Load(). This is already ridiculous, but it still cannot be used because the _renderOptions variable is only set in a single place and is immediately used for the _pipeline creation (not giving you chance to change it using the WindowCenter property). Your only chance is the grayscale _renderOptions initialization: _renderOptions = GrayscaleRenderOptions.FromDataset(Dataset);.
The current solution: Your dataset should have
DicomTag.WindowCenter set appropriately
DicomTag.WindowWidth != 0.0
DicomTag.PhotometricInterpretation == Monochrome1 or Monochrome2
The following code accomplishes that:
DicomDataset dataset = DicomFile.Open(fileName).Dataset;
//dataset.Set(DicomTag.WindowWidth, 200.0); //the WindowWidth must be non-zero
dataset.Add(DicomTag.WindowCenter, "100.0");
//dataset.Add(DicomTag.PhotometricInterpretation, "MONOCHROME1"); //ValueRepresentations tag is broken
dataset.Add(new DicomCodeString(DicomTag.PhotometricInterpretation, "MONOCHROME1"));
DicomImage image = new DicomImage(dataset);
image.RenderImage();
The best solution: Wait while this buggy library is fixed.
I have a report designed in Crystal Rerports 12x8.5 inch. I have my OKI 3320 printer driver set exactly to this size.
Now, when I print the report using my C# code, the page length is half inch short of the tear off position. I have to roll up paper to tear it off. Is there any settings we can change through code to exactly get to the tear off position?
ReportDocument oReportDocument = new ReportDocument();
oReportDocument.Load(reportPath + "\\OutDkt.rpt");
List<TblOutDocket> lstDockets = new List<TblOutDocket>();
lstDockets.Add(oTblOutDocket);
oReportDocument.SetDataSource(lstDockets);
oReportDocument.PrintOptions.PrinterName = LocalPrintServer.GetDefaultPrintQueue().FullName;
oReportDocument.PrintToPrinter(1, false, 0, 0);
It seems when you are using custom page sizes you need to specify the page settings specifically. According to this link you can achieve this by setting the PageSettings namespace.
When you want to use a papersize with an id greater then 118 (Windows
coded papersize) you must supply the id of your papersize to
PrintOptions.PaperSource. Obviuosly you need to cast it at
CrystalDecisions.Shared.PaperSource I do this:
ReportDocument.PrintOptions.PaperSource =
(CrystalDecisions.Shared.PaperSource)m_PageSettings.PaperSource.RawKind;
ReportDocument.PrintOptions.PaperSize =
(CrystalDecisions.Shared.PaperSize)m_PageSettings.PaperSize.RawKind;
Where m_PageSettings is my System.Drawing.PageSettings that specify
the right PaperSize