A couple of days ago I asked this question:
Itext PDF How To Add HTML Pre-formatted to PDF, but #bruno-lowagie told me to follow instructions on this existing thread: How To Add HTML Headers And Footers to a Page, I followed carefully the instructions, but found that that approach works for simple html headers and footers like:
<h1>Header Only Line</h1>
or
<h2>Footer Only Line</h2>
But my use case requires to add more complex data in header and footer like images, So I tried with a header that has an img element pointing to an image in the same server like this:
http://localhost:8080/DocGen/resources/images/main_header.jpg
I added some start and end "marks" to see if they got processed so my header was like this:
<p>----Header Start---</p>
<p><img alt="" src="http://localhost:8080/DocGen/resources/images/main_header.jpg" style="height:126px; width:683px" /></p>
<p>--Header End--</p>
But I'm getting an output pdf like this:
Edited: As you can see it doesn't show the image and didn't also show my end mark.
What should I do to successfully add headers and footers with images embedded?
Thanks a lot.
P.S: Sorry for any inconvenience as I am new here, and I hope my question is clear.
EDIT: Code, it's like in the other thread:
public class HtmlHeaderFooter {
private String DEST = null;//"results/events/html_header_footer.pdf";
private String HEADER = null;
private String FOOTER = null;
private float leftMargin;
private float rightMargin;
private float topMargin;
private float bottomMargin;
private Rectangle pageSize = null;
public class HeaderFooter extends PdfPageEventHelper {
protected ElementList header;
protected ElementList footer;
public HeaderFooter() throws IOException {
header = XMLWorkerHelper.parseToElementList(HEADER, null);
footer = XMLWorkerHelper.parseToElementList(FOOTER, null);
}
#Override
public void onEndPage(PdfWriter writer, Document document) {
try {
ColumnText ct = new ColumnText(writer.getDirectContent());
ct.setSimpleColumn(new Rectangle(36, 832, 559, 810));
for (Element e : header) {
System.out.println("Element on header: " + e.toString());
ct.addElement(e);
}
ct.go();
ct.setSimpleColumn(new Rectangle(36, 10, 559, 32));
for (Element e : footer) {
System.out.println("Element on footer: " + e.toString());
ct.addElement(e);
}
ct.go();
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}
}
public void createPdfAlt(String outputFile, String inputFile){
Document document = new Document(pageSize, leftMargin, rightMargin, topMargin, bottomMargin);
FileOutputStream outputStream;
try {
outputStream = new FileOutputStream(DEST);
//System.out.println("Doc: " + document.);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
writer.setPageEvent(new HeaderFooter());
document.open();
PdfContentByte cb = writer.getDirectContent();
// Load existing PDF
PdfReader reader = new PdfReader(new FileInputStream(inputFile));
PdfImportedPage page = writer.getImportedPage(reader, 1);
// document.setPageSize(reader.getPageSize(1));
// Copy first page of existing PDF into output PDF
document.newPage();
cb.addTemplate(page, 0, 0);
document.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In my Managed Bean I set Header, Footer, outputfile and so on:
HtmlHeaderFooter htmlHeaderFooter = new HtmlHeaderFooter();
htmlHeaderFooter.setFOOTER(footerContent);
htmlHeaderFooter.setHEADER(headerContent);
//htmlHeaderFooter.setPageSize(xml2pdf.getPageSize());
htmlHeaderFooter.setPageSize(com.itextpdf.text.PageSize.A4);
htmlHeaderFooter.setLeftMargin(template2Export.getLeftMargin());
htmlHeaderFooter.setRightMargin(template2Export.getRightMargin());
htmlHeaderFooter.setTopMargin(template2Export.getSuperiorMargin());
htmlHeaderFooter.setBottomMargin(template2Export.getInferiorMargin());
htmlHeaderFooter.setDEST("salidaConHeaderAndFooter.pdf");
htmlHeaderFooter.createPdfAlt("PDFCompleto1.pdf", "test3.pdf");
EDIT 2: Header should look like this
If you are talking about the html code "as is" it's like this:
<p>----Header Start---</p>
<p><img alt="" src="http://localhost:8080/DocGen/resources/images/main_header.jpg" style="height:126px; width:683px" /></p>
<p>--Header End--</p>
You draw the header here:
ct.setSimpleColumn(new Rectangle(36, 832, 559, 810));
So you allow for about 22pt height (832 - 810) to draw all the header material.
On the other hand your header is expected to display this
<p>----Header Start---</p>
<p><img alt="" src="http://localhost:8080/DocGen/resources/images/main_header.jpg" style="height:126px; width:683px" /></p>
<p>--Header End--</p>
This header requires two paragraphs plus 126px (94.5pt). Thus, it does not fit. Consequently, only the first paragraph (which is the only header content that fits) is drawn.
You might want to start by allowing a lot of space, e.g.
ct.setSimpleColumn(new Rectangle(36, 832, 559, 0));
and then reduce it step by step according to your requirements.
Related
my application connects to a database in mysql using phpmyadmin and stores an image in the database, but my problem is when I download the image from the database and post the image on a imageview the image has a very low quality where also it's color is being afected too.
if I post the image directly on the database using phpmyadmin and then download the image using my app the image looks fine, but if I upload the image from my app and then i download it then the quality is bad.
the way to post the image is past the image to a byte[] and then uploading to the database that uses the type blob.
private byte[] imagenToByte(Image imagen) {
BufferedImage bufferimage = SwingFXUtils.fromFXImage(imagen, null);
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
ImageIO.write(bufferimage, "jpg", output );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte [] data = output.toByteArray();
return data;
}
can you help me please?
EDIT
#FXML
public void eventoBotonSeleccionarImagen() {
FileChooser imagenSeleccionada = new FileChooser();
FileChooser.ExtensionFilter filtroImagenjpg = new ExtensionFilter("Archivos *.jpg", "*.jpg");
FileChooser.ExtensionFilter filtroImagenJPG = new ExtensionFilter("Archivos *.JPG", "*.JPG");
File archivo = imagenSeleccionada.showOpenDialog(null);
try {
BufferedImage bufferedImage = ImageIO.read(archivo);
Image image = SwingFXUtils.toFXImage(bufferedImage, null);
imageViewMonstruo.setImage(image);
}
catch(Exception e) {
e.printStackTrace();
}
}
I found the answer to the question thanks to this
this question.
What I've done is changing from Blob to longblob in the database and adding png instead of jpg, the code result is this
private byte[] imagenToByte(Image imagen) {
BufferedImage bufferimage = SwingFXUtils.fromFXImage(imagen, null);
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
ImageIO.write(bufferimage, "png", output );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte [] data = output.toByteArray();
return data;
}
And finally it upload and download the images with the same quality
I am using tess4j api for reading an image for numerics.
code as below:
public static void main(String[] args) {
// TODO Auto-generated method stub
final File imageFile = new File("C:\\Users\\goku\\Desktop\\myimage.png");
System.out.println("Image found");
final ITesseract instance = new Tesseract();
instance.setTessVariable("tessedit_char_whitelist", "0123456789");
instance.setDatapath("C:\\Users\\goku\\Downloads\\Tess4J");
instance.setLanguage("eng");
String result;
try {
result = instance.doOCR(imageFile);
System.out.println(result);
} catch (TesseractException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Image attached.
The program is reading the numerics as wrong. Not able to find the issue.
output:
1 1 3 251
regards,
Vasu
Rescaling the image to 300 DPI would get the correct result.
This is how to properly edit image with im4java (imagemagick) so it can be read with tess4j (tesseract):
private static File processImage(File img) throws IOException {
File newImg = File.createTempFile("asdf", ".png");
ImageMagickCmd cmd = new ImageMagickCmd("convert");
IMOperation op = new IMOperation();
op.addImage(img.getAbsolutePath());
op.strip().resample(300).colorspace("gray").autoLevel().threshold(35000).type("bilevel").depth(8).trim();
op.addImage(newImg.getAbsolutePath());
cmd.run(op);
return newImg;
}
It might be the trained data. I have used the trained data from the tesseract-ocr-w64-setup-v4.1.0.20190314.exe Windows binary, found at https://digi.bib.uni-mannheim.de/tesseract/, with the datapath set as below
instance.setDatapath("C:\\Program Files\\Tesseract-OCR\\tessdata");
I do get a warning about the resolution, but the result is correct:
471871882819
I use MySql db with images in blob and try to display them on my JSF page using PrimeFaces galleria. On my page I see this galleria, but images aren't displayed. I see only small green icons in a corner of every image. I get this problem only using DB. If my images are in my file system, everything will be OK. Can someone explain why I can't see images from DB? I wrote this code:
Galleria:
<p:galleria value="#{imagesView.images}" var="image" panelWidth="500" panelHeight="250" showCaption="true">
<p:graphicImage value="#{image}" alt="Image Description" title="Title"/>
</p:galleria>
ImagesView:
#ManagedBean
public class ImagesView {
private List<StreamedContent> images;
#PostConstruct
public void init() {
images = new ArrayList<>();
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
int itemId = Integer.parseInt(request.getParameter("item_id"));
for (int i = 1; i <= 2; i++) {
images.add(new GraphicImage().getImageFromDB(i, itemId)); //It's so simple because I need it just for test and that's all
}
}
public List<StreamedContent> getImages() {
return images;
}
}
GraphicImage:
#RequestScoped
class GraphicImage implements Serializable {
StreamedContent getImageFromDB(int id, int itemId) {
if (FacesContext.getCurrentInstance().getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
} else {
byte[] image = DBUtils.getImage(id, itemId);
return new DefaultStreamedContent(new ByteArrayInputStream(image), "image/jpg");
}
}
}
DBUtils method:
public static byte[] getImage(int id, int itemId) {
byte[] image = null;
ResultSet resultSet = null;
try (Connection connection = DataBase.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT content FROM images WHERE id = ? AND item_id = ?")) {
statement.setInt(1, id);
statement.setInt(2, itemId);
resultSet = statement.executeQuery();
resultSet.next();
image = resultSet.getBytes("content");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (resultSet != null) resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return image;
}
It's not how a p:graphicImage works. You're trying to display an image using a byte array while this tag requires an URL to the image (or a StreamedContent).
<p:graphicImage value="img/myImg.png" />
Now, you have 2 options (at least)
either create an image from your byte array (image data) and store
it somewhere where it's accessible by your web application. The value attribute should still contain an URL rather than a byte array.
don't store images in your DB, but rather store an image name (or
path to a image on the server ) (e.g. your DB will just constain
img001.png, img002 png etc and you know they're all inside, say, the img
folder on your server. Then, all you have to do is change the image URL.
<p:graphicImage value=#{imgUrl} />
Option 2 is actually recommended especially for large images, but even when your images are not large this method has the advantage of not having to convert images (byte arrays) to files.
In your HTML, this will be rendered as
<img src="img/img001.png" >
I want to convert the raw html code to pdf file.
This is my Controller code
#RequestMapping("getpdf")
public void doGet(HttpServletRequest request,
HttpServletResponse response,String ref){
OutputStream out = null;
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
java.util.List items = null;
ArticalBean abean=serviceLayer.getArtical(Integer.parseInt(ref));
items = new ArrayList();
items.add(abean.getArticle());
try {
response.setContentType("application/pdf");
PdfWriter.getInstance(document, response.getOutputStream());
document.open();
Paragraph paragraph = new Paragraph("Microweb Systems");
document.add(paragraph);
ListItem listItem;
com.lowagie.text.List list = new com.lowagie.text.List(true, 15);
Iterator i = items.iterator();
while(i.hasNext()) {
listItem = new ListItem((String)i.next(),
FontFactory.getFont(FontFactory.TIMES_ROMAN, 12));
list.add(listItem);
}
document.add(list);
} catch (Exception e) {
} finally {
document.close();
}
document.close();
}
It converts the HTML codes to PDF but that pdf also contains the tags
Like
<h1>Hello World</h1>
Is there is any way to remove these tags and show only Data.
I am providing the data from database via DTO.
If I understand your question, you want to remove the tags.
This can be done with String.replaceAll(String regex, String replacement).
For example myString.replaceAll("^<[.]*>$" , ""); would remove any tags.
This, however, does not make the pdf look like the page does in a browser.
I have a json array of image URLs added into an observable collection and I want to display the first image on the page such that when a user scrolls horizontally, next or previous images in the array shall display on the screen. Help me achieve this.
Here's how I download the image URLs via json and add them to the observable collection
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<readPageModel> readPages = new ObservableCollection<readPageModel>();
public ObservableCollection<readPageModel> Read_Pages
{
get
{
return readPages;
}
set
{
readPages = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Read_Pages"));
}
}
}
public void DownloadData()
{
WebClient client = new WebClient();
client.DownloadStringCompleted += client_DownloadStringCompleted;
client.DownloadStringAsync(new Uri("http://########/mob/ranges/id/3/limit/10/offset/0/r_id/6", UriKind.Absolute));
}
private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
if (!string.IsNullOrEmpty(e.Result))
{
string data = e.Result;
var items = JsonConvert.DeserializeObject<readModel[]>(data);
foreach (var x in items)
{
Read_Pages.Add(x);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
You can take scrollviwer in the xaml after this within this scrollviewer take stack panel with horizontal orientation. and then from c# code add image control to this stack panel.
You can have one image control in content panel and implement below code :
public Page()
{
InitializeComponent();
GestureListener gestureListener = GestureService.GetGestureListener(ContentPanel);
gestureListener.DragCompleted += gestureListener_DragCompleted;
//set the initial image to Image control
}
void gestureListener_DragCompleted(object sender, DragCompletedGestureEventArgs e)
{
// User flicked towards left
if (e.HorizontalVelocity < 0)
{
// Load the next image if Downloaded
}
// User flicked towards right
if (e.HorizontalVelocity > 0)
{
// Load the previous image
}
}
you would also needed to have one variable for tracking the index of image to be loaded