I want to print a PDFFile object from the Pdf-Renderer library using javafx printing. Is it possible to print non Node objects? Currently i'm using AWT printing (check this example) but it doesn't go well with javafx because my javafx window freezes when the AWT print dialog comes up.
Printer printer = Printer.getDefaultPrinter();
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.DEFAULT);
PrinterJob job = PrinterJob.createPrinterJob();
if (job != null) {
boolean success = job.printPage(node); // use something otherthan a node(PDFFile in my case)
if (success) {
job.endJob();
}
}
You can get a java.awt.Image from each page, draw the page to a java.awt.image.BufferedImage convert the BufferedImage to a javafx.scene.image.Image, and finally print an ImageView containing the image:
Something like:
PrinterJob job = PrinterJob.createPrinterJob();
PDFFile pdfFile = ... ;
if (job != null) {
boolean success = true ;
for (int pageNumber = 1; pageNumber <= pdfFile.getNumPages() ; pageNumber++) {
PDFPage page = pdfFile.getPage(pageNumber, true);
Rectangle2D bounds = page.getBBox();
int width = (int) bounds.getWidth();
int height = (int) bounds.getHeight();
java.awt.Image img = page.getImage(width, height, bounds, null, true, true);
BufferedImage bImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
bImg.createGraphics().drawImage(img, 0, 0, null);
javafx.scene.image.Image fxImg = SwingFXUtils.toFXImage(bImg, null);
ImageView imageView = new ImageView(fxImg);
success = success & job.printPage(imageView);
}
if (success) {
job.endJob();
}
}
Note that this code can be executed off the FX Application Thread, to keep the UI responsive.
Related
I need one help.
I am using Appium and I have a scenerio wherein I need to capture an image from the app under test, preserve that image as a baseline image and then capture another image from that app under test and then perform an image comparison between these two images.
Can anyone guide me how to do this please.
This is how you do it:
#Test(dataProvider = "search")
public void eventsSearch(String data) throws InterruptedException, IOException {
Thread.sleep(2000);
boolean status = false;
//WebElement img = driver.findElementByClassName("android.widget.ImageView");
//take screen shot
File screen = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
// for (String event : events) {
driver.findElementById("your id")
.sendKeys(data);
driver.hideKeyboard();
List<WebElement> list = driver
.findElementsByXPath("//*[#class='android.widget.TextView' and #index='1']");
System.out.println(list.size());
int i = 0;
for (WebElement el : list) {
String eventList = el.getText();
System.out.println("events" + " " + eventList);
if (eventList.equals("gg")) {
status = true;
break;
}
i++;
}
//capture image of searched contact icon
List<WebElement > imageList = driver.findElementsByXPath("//*[#class='android.widget.ImageView' and #index='0']");
System.out.println(imageList.size());
System.out.println(i);
WebElement image = imageList.get(1);
Point point = image.getLocation();
//get element dimension
int width = image.getSize().getWidth();
int height = image.getSize().getHeight();
BufferedImage img = ImageIO.read(screen);
BufferedImage dest = img.getSubimage(point.getX(), point.getY(), width,
height);
ImageIO.write(dest, "png", screen);
File file = new File("Menu.png");
FileUtils.copyFile(screen, file);
//verify images
verifyImage("Menu.png", "Menu.png" );
//Assert.assertTrue(status, "FAIL Event doesn't match" + data);
}
#DataProvider(name = "search")
public Object[][] searchData() {
return new Object[][] { { "gg" } };
}
public void verifyImage(String image1, String image2) throws IOException{
File fileInput = new File(image1);
File fileOutPut = new File(image2);
BufferedImage bufileInput = ImageIO.read(fileInput);
DataBuffer dafileInput = bufileInput.getData().getDataBuffer();
int sizefileInput = dafileInput.getSize();
BufferedImage bufileOutPut = ImageIO.read(fileOutPut);
DataBuffer dafileOutPut = bufileOutPut.getData().getDataBuffer();
int sizefileOutPut = dafileOutPut.getSize();
Boolean matchFlag = true;
if(sizefileInput == sizefileOutPut) {
for(int j=0; j<sizefileInput; j++) {
if(dafileInput.getElem(j) != dafileOutPut.getElem(j)) {
matchFlag = false;
break;
}
}
}
else
matchFlag = false;
Assert.assertTrue(matchFlag, "Images are not same");
}
I am developing a POS application in windows 8.1 (Universal App).
Order receipt will be printed from the application and even I am able to do so.
Printer - EPSON TM-U220D
Input - A grid is being created pragmatically with dynamic content within the ViewModel. So this grid is the input for printer
Output - In the print preview (Attahced pic 1) all looks good but when the receipt is actually printed then content is cut off from the end (Attahced pic 2)
PIC 1
PIC 2
Observations -
If I print a normal text file manually using print command (Right click file and then print), then all content is printed perfectly.
If I print that SAME content, from the application, by creating Dynamic grid, then with Small font size print is good but with bit bigger font size content again cuts off.
Tried -
Optimized the code for Creating Gird, by specifying height
Questions-
If preview is all good then why not output
Did anyone tried using ePOS-Print_SDK_141020E for Windows Store app?
Generate Dynamic Grid Code
private void AddRows(Grid grid, int count)
{
for (int i = 0; i < count; i++)
{
RowDefinition row = new RowDefinition();
row.Height = GridLength.Auto;
grid.RowDefinitions.Add(row);
}
}
private void AddColumns(Grid grid, int count)
{
for (int i = 0; i < count; i++)
{
grid.ColumnDefinitions.Add(new ColumnDefinition());
}
}
private TextBlock CreateTextBlock(string text, Color color, FontWeight fw, double fs = 10, int thick = 5)
{
if (color == null) color = Colors.Black;
TextBlock txtBlock1 = new TextBlock();
txtBlock1.Text = text;
txtBlock1.FontSize = fs;
txtBlock1.FontWeight = fw;
txtBlock1.Foreground = new SolidColorBrush(color);
txtBlock1.VerticalAlignment = VerticalAlignment.Center;
txtBlock1.Margin = new Thickness(thick);
return txtBlock1;
}
private async Task<Grid> CreateDynamicWPFGrid()
{
Grid ParentGrid = new Grid();
AddRows(ParentGrid, 8);
/* Start First Grid*/
Grid DynamicGrid = new Grid();
DynamicGrid.Width = 230;
DynamicGrid.HorizontalAlignment = HorizontalAlignment.Left;
DynamicGrid.VerticalAlignment = VerticalAlignment.Top;
DynamicGrid.Margin = new Thickness(24, 0, 0, 0);
AddColumns(DynamicGrid, 2);
AddRows(DynamicGrid, 3);
TextBlock txtBlock1 = CreateTextBlock(DateTime.Now.ToString("M/d/yy"), Colors.Black, FontWeights.Normal);
Grid.SetRow(txtBlock1, 0);
Grid.SetColumn(txtBlock1, 1);
.
.
.
.
Return ParentGrid;
}
Printer Events Code
//Register Print Contract
async Task RegisterPrintContract()
{
PrintManager manager = PrintManager.GetForCurrentView();
manager.PrintTaskRequested += OnPrintTaskRequested;
await PrintManager.ShowPrintUIAsync();
}
//Unregister Print Contract
void UnregisterPrintContract()
{
PrintManager printMan = PrintManager.GetForCurrentView();
printMan.PrintTaskRequested -= OnPrintTaskRequested;
}
void OnPrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
// If I need to be asynchronous, I can get a deferral. I don't *need*
// to do this here, I'm just faking it.
var deferral = args.Request.GetDeferral();
PrintTask printTask = args.Request.CreatePrintTask("My Print Job", OnPrintTaskSourceRequestedHandler);
printTask.Completed += OnPrintTaskCompleted;
deferral.Complete();
}
void OnPrintTaskCompleted(PrintTask sender, PrintTaskCompletedEventArgs args)
{
// TODO: Tidy up.
this._document = null;
this._pages = null;
}
async void OnPrintTaskSourceRequestedHandler(PrintTaskSourceRequestedArgs args)
{
var deferral = args.GetDeferral();
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
this._document = new PrintDocument();
this._document.Paginate += OnPaginate;
this._document.GetPreviewPage += OnGetPreviewPage;
this._document.AddPages += OnAddPages;
// Tell the caller about it.
args.SetSource(this._document.DocumentSource);
});
deferral.Complete();
}
void OnAddPages(object sender, AddPagesEventArgs e)
{
// Loop over all of the preview pages and add each one to add each page to be printied
// We should have all pages ready at this point...
foreach (var page in this._pages)
{
//this._pages[page.Key]
this._document.AddPage(this._pages[page.Key]);
}
PrintDocument printDoc = (PrintDocument)sender;
// Indicate that all of the print pages have been provided
printDoc.AddPagesComplete();
}
async void OnGetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
Grid x = await CreateDynamicWPFGrid();
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// NB: assuming it's ok to keep all these pages in
// memory. might not be the right thing to do
// of course.
if (this._pages == null)
{
this._pages = new Dictionary<int, UIElement>();
}
if (!this._pages.ContainsKey(e.PageNumber))
{
this._pages[e.PageNumber] = x;
}
if (this._document == null)
this._document = new PrintDocument();
this._document.SetPreviewPage(e.PageNumber, this._pages[e.PageNumber]);
}
);
}
async void OnPaginate(object sender, PaginateEventArgs e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// I have one page and that's *FINAL* !
this._document.SetPreviewPageCount(e.CurrentPreviewPageNumber, PreviewPageCountType.Final);
});
}
Document is printed from MVC controller to Debian Squeeze Linux server printer using code below in Mono.
Page in printer is A4.
Printed text in paper is too big and unsharp. Rightmost part of text is not visible since it does not fit to page.
If printed from Windows from .NET to HP Laserjet, output is correct.
So it looks like Mono or Samsung ML-331x Series printer zooms bitmap for unknown reason which causes too big and unsharp output.
How to fix this so that bitmap is printed like in windows ?
Possible solutions:
Best way would be to print formatted html directly. How to do it in server where there are no browser installed? wkhtmltopdf does not support printing. I posted it in How to print formatted html in Linux server
Maybe it is possible to use wkhtmltopdf convert html to pdf instead of bitmap I posted it as separate question in How to print pdf in debian linux from MVC controller
wkhtmltoimage can produce also other image formats. Maybe some other format is better ?
Maybe some wkhtmltoimage command line swithches like --width=750 or --dpi can fix this ?
public class Test: Controller
{
public ActionResult Print()
{
PrintOrderVormiga();
return new ContentResult() { Content = "OK" };
}
void PrintOrderVormiga()
{
StringBuilder sb = new StringBuilder();
sb.Insert(0, " test ", 500);
var bmp = ConvertHtmlToBMP("<html><body>" +sb.Tostring()+ "</body></html>");
var doc = new PrintDocument();
doc.PrinterSettings.PrinterName = "Samsung ML-331x Series";
doc.PrintPage += new PrintPageEventHandler(ProvideContent);
pageHeight = doc.DefaultPageSettings.PaperSize.Height;
using (bm = new Bitmap(new MemoryStream(bmp)))
{
lehti = (int)Math.Ceiling(bm.Height / (double)pageHeight);
doc.PrinterSettings.FromPage = 1;
doc.PrinterSettings.ToPage = lehti;
pageno = 0;
doc.Print();
}
}
int pageno, lehti;
int pageHeight;
Bitmap bm;
void ProvideContent(object sender, PrintPageEventArgs e)
{
Rectangle cropRect = new Rectangle(0, pageHeight * pageno++,
bm.Width, pageHeight);
Bitmap target = new Bitmap(cropRect.Width, cropRect.Height);
e.Graphics.DrawImage(bm, new Rectangle(0, 0, target.Width, target.Height),
cropRect,
GraphicsUnit.Pixel);
e.HasMorePages = pageno < lehti;
}
static byte[] ConvertHtmlToBMP(string html)
{
string programm = "wkhtmltoimage";
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
{
programm = "wkhtmltoimage-amd64";
}
var p = new Process
{
StartInfo =
{
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UseShellExecute = false,
FileName = Environment.OSVersion.Platform == PlatformID.Win32NT ?
"C:\\Program Files\\wkhtmltopdf\\bin\\" + programm + ".exe" : "/usr/bin/" + programm
}
};
p.StartInfo.Arguments = "--format bmp --disable-javascript --quality 10";
p.StartInfo.Arguments += " - -";
p.Start();
using (var stream = p.StandardInput)
{
byte[] ibuffer = System.Text.Encoding.UTF8.GetBytes(html);
stream.BaseStream.Write(ibuffer, 0, ibuffer.Length);
stream.WriteLine();
}
var buffer = new byte[32768];
byte[] file;
using (var ms = new MemoryStream())
{
while (true)
{
var read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
if (read <= 0)
{
break;
}
ms.Write(buffer, 0, read);
}
file = ms.ToArray();
}
p.WaitForExit(60000);
var returnCode = p.ExitCode;
p.Close();
return file;
}
}
You can use this HTML to PDF Converter for Mono solution from EvoPdf. The C# code for converting a HTML to PDF in Mono is:
// create the HTML to PDF converter object
HtmlToPdfConverter htmlToPdfConverter = new HtmlToPdfConverter(serverIPAddress, serverPortNumber);
// set service password if necessary
if (serverPassword.Length > 0)
htmlToPdfConverter.ServicePassword = serverPassword;
// set PDF page size
htmlToPdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
// set PDF page orientation
htmlToPdfConverter.PdfDocumentOptions.PdfPageOrientation = PdfPageOrientation.Portrait;
// convert the HTML page from given URL to PDF in a buffer
byte[] pdfBytes = htmlToPdfConverter.ConvertUrl(urlToConvert);
Sory for my english. I want attach image from gallery and show in edit text with SpannableStringBuilder. I have success for get Image Path from Gallery. After picture selected, Picture Show. But, for the second attach image picture not show and first image attach became a text. any one give me solution ? big thanks.
this is my code:
private void IntentPict() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select File"),MY_INTENT_CLICK);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK){
if (requestCode == MY_INTENT_CLICK){
if (null == data) return;
String selectedImagePath;
Uri selectedImageUri = data.getData();
//there is no problem with get path
selectedImagePath = ImageFilePath.getPath(getApplicationContext(), selectedImageUri);
//pathImag is ListArray<String>
pathImg.add(selectedImagePath);
addImageBetweentext(pathImg);
}
}
}
private void addImageBetweentext(ArrayList<String> listPath) {
SpannableStringBuilder ssb = new SpannableStringBuilder();
for(int i=0;i<listPath.size();i++){
String path = listPath.get(i);
Drawable drawable = Drawable.createFromPath(path);
drawable.setBounds(0, 0, 400, 400);
ssb.append(mBodyText+"\n");
ssb.setSpan(new ImageSpan(drawable), ssb.length()-(path.length()+1),
ssb.length()-1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
mBodyText.setText(ssb);
}
Here's something that should work. I am loading resource drawables instead, just because it was quicker for me to validate, but I tried to keep as mich as possible for your original flow and variable names:
Drawable[] drawables = new Drawable[2];
drawables[0] = getResources().getDrawable(R.drawable.img1);
drawables[1] = getResources().getDrawable(R.drawable.img2);
SpannableStringBuilder ssb = new SpannableStringBuilder();
for (int i = 0; i < drawables.length; i++) {
Drawable drawable = drawables[i];
drawable.setBounds(0, 0, 400, 400);
String newStr = drawable.toString() + "\n";
ssb.append(newStr);
ssb.setSpan(
new ImageSpan(drawable),
ssb.length() - newStr.length(),
ssb.length() - "\n".length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
mBodyText.setText(ssb);
Long story short: the start position for the incremental builder needs to be set to the current length of it, minus what you just added.
I am developing a module in a billing system for a national Utility. The module is supposed to pick all successfully billed customers and print their bills.Bills are written as text files and saved on a local folder and the program has to pick them up and print them one by one.I'm using a DFX-9000 printer and pre-formatted roll paper,however,each time a new bill comes in,the printer skips some space before it prints it which distorts the 2nd and following bills.
I tried putting all the bills in a single text file which prints well when opened in notepad but not in my code.
Here is part of my code
Font printFont = new Font("Lucida Console", 10);
//static string filename;
StreamReader reader = new StreamReader(Filename);
public void Print()
{
try
{
PrintDocument pd = new PrintDocument();
pd.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("myPaper", 826, 1169);
pd.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
//pd.DefaultPageSettings.PrinterSettings.IsPlotter = true;
pd.DefaultPageSettings.PrinterResolution.Kind = PrinterResolutionKind.Custom;
pd.PrintPage += new PrintPageEventHandler(this.PrintTextFileHandler);
pd.Print();
if (reader != null)
reader.Close();
Console.WriteLine("Printout Complete");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void PrintTextFileHandler(object sender, PrintPageEventArgs pe)
{
StringFormat sf = new StringFormat();
Graphics g = pe.Graphics;
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = 40;//pe.MarginBounds.Left;
float topMargin = pe.MarginBounds.Top;
string line = null;
linesPerPage = 500;// pe.MarginBounds.Height / printFont.GetHeight(g);
while (count <= linesPerPage &&((line = reader.ReadLine()) != null))
{
yPos = topMargin + (count * printFont.GetHeight(g));
g.DrawString(line, printFont, Brushes.Black, leftMargin, yPos);
count++;
}
if (line != null)
{
pe.HasMorePages = true;
}
else
{
pe.HasMorePages = false;
}
Could your printing.papersize be wrong? I notice it's 1169, doesn't standard paper stop at 1100?