Starting with an InputStream, use PDFBox to add a text image to the PDF and finish with the original InputStream variable - inputstream

I'm having some trouble understanding how PDFBox works so I'm hoping someone can help me out here. Here is my code:
InputStream content=null;
try{
content = document.getImageStream(1);
//Add image of word "Approved" at specific x and y coordinate in PDF
//Do more stuff with InputStream content
I already have a bunch of code below that uses that InputStream so what I would like to do is use PDFBox to "update" the PDF that the InputStream holds by adding a textbox at a given x and y coordinate and then still have the same InputStream at the end so I can continue doing stuff with it.
All I know so far is to create a PDDocument from the InputStream like this:
PDDocument pddocument = PDDocument.load(content);
Thank you for the help!

Related

Flying-saucer/iText PDF not finding css file

I can generate a PDF using flying-saucer/iText. However, I can't figure out how to get the style sheet included in the PDF rendering.
I have used this flying-saucer/iText PDF in servlet not finding css file as reference.
There are multiple css files involved so I won't be able to use renderer.setDocument(doc, "http://example.com/something/page.html");
as a solution
I have implemented a something similar to what the asker used, but it's returning a Caused by: java.nio.file.InvalidPathException: Illegal char <:> at index 4: http://localhost:8080/proj/resources/css/custom1.css error
Here is my code
StringBuilder bui = new StringBuilder();
bui.append("<html><head><style>");
bui.append(readFile(path+"/resources/css/custom1.css", Charsets.UTF_8));
bui.append(readFile(path+"/resources/css/custom2.css", Charsets.UTF_8));
bui.append(readFile(path+"/resources/css/custom3.css", Charsets.UTF_8));
bui.append("</style></head>");
bui.append("<body><div><table>");
bui.append( xhtml_file );
bui.append("</table></div></body></html>");
InputStream stream = new ByteArrayInputStream(bui.toString().getBytes( StandardCharsets.UTF_8 ));
Document doc = tidy.parseDOM(stream, null);
File outputFile = new File(directory+ "FILENAME" +".pdf");
os = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(doc, null);
renderer.layout();
renderer.createPDF(os, false);
renderer.finishPDF();
the path being passed is "http://localhost:8080"
if I enter "http://localhost:8080/resources/css/custom1.css" directly into the address bar, it shows the css file. I tried removing the 'path' but it's also not getting the css. What am I doing wrong?
Try the file:/// url protocol to point (with three slashes) pointing to the css file directly.

Is there a cross-platform solution to ImageSource to byte[]?

I did researches and fell on this solution: http://forums.xamarin.com/discussion/22682/is-there-a-way-to-turn-an-imagesource-into-a-byte-array
Initial question: http://forums.xamarin.com/discussion/29569/is-there-a-cross-platform-solution-to-imagesource-to-byte#latest
We want to upload an image through a HTTP Post, here's what we tried:
HttpClient httpClient = new HttpClient ();
byte[] TargetImageByte = **TargetImageSource**; //How to convert it to a byte[]?
HttpContent httpContent = new ByteArrayContent (TargetImageByte);
httpClient.PostAsync ("https://api.magikweb.ca/debug/file.php", httpContent);
We also are having a hard time with the libraries we gotta include in the using clauses. It seems like using System.IO; works, but it doesn't give us access to classes like FileInfo or FileStream.
Anybody has any idea how this can be done aside from custom platform-specific converters?
Possibly a Xamarin.Forms.ImageSource function toByte()?
Lemme know if you need more information.
TargetImageSource is a Xamarin.Forms.ImageSource.
ImageSource TargetImageSource = null;
Solution (Sten was right)
The ImageSource has to originate from another type to exist, that previous type can be converted to a byte[]. In this case, I use the Xamarin.Forms.Labs to take a picture and it returns a MediaFile in which a FileStream is accessible through the Source property.
//--Upload image
//Initialization
HttpClient httpClient = new HttpClient ();
MultipartFormDataContent formContent = new MultipartFormDataContent ();
//Convert the Stream into byte[]
byte[] TargetImageByte = ReadFully(mediaFile.Source);
HttpContent httpContent = new ByteArrayContent (TargetImageByte);
formContent.Add (httpContent, "image", "image.jpg");
//Send it!
await httpClient.PostAsync ("https://api.magikweb.ca/xxx.php", formContent);
App.RootPage.NavigateTo (new ClaimHistoryPage());
The function:
public static byte[] ReadFully(Stream input)
{
using (MemoryStream ms = new MemoryStream()){
input.CopyTo(ms);
return ms.ToArray();
}
}
I think you're looking at it a bit backwards.
ImageSource is a way to provide a source image for Xamarin.Forms.Image to show some content. If you're already showing something on the screen your Image view was populated with data that came from elsewhere, such as a file or resource or stored in an array in memory... or however else you got that in the first place. Instead of trying to get that data back from ImageSource you can keep a reference to it and upload it as needed.
Maybe you can elaborate a bit on your particular need if you don't feel this solution applies to your case.
Pseudo code:
ShowImage(){
ImageSource imageSource = ImageSource.FromFile("image.png"); // read an image file
xf_Image.Source = imageSource; // show it in your UI
}
UploadImage(){
byte[] data = File.ReadAll("image.png");
// rather than
// byte[] data = SomeMagicalMethod(xf_Image.Source);
HttpClient.Post(url, data);
}
UPDATE:
Since you're taking a picture you can copy the MediaFile.Source stream into a memory stream, then you can reset the memory stream's position to point at the beginning of the stream so that you can read it once again and copy it to the http body.
Alternatively you can store the MediaFile.Source to a file and use ImageSource.FromFile to load it in the UI, and when necessary - you can copy the file's contents into an http post body.

Dynamics AX CompanyImage to Image File

I need to export the images stored in CompanyImage table to a image files.
How can I do it?
Reading the table I obtain a Bitmap field but how to know the type of image to build the correct extension and save it to file?
Finally I found the solution.
To export the image from CompanyImage:
// Grant clrinterop permission.
new InteropPermission(InteropKind::ClrInterop).assert();
image = new Image();
image.setData(companyImage.Image);
result = image.saveImage(#"c:\test.jpg",3);
CodeAccessPermission::revertAssert();
To know the original type:
image.saveType();
The above code wouldn't work right away. Here's the code that would run:
bindata bin = new bindata();
str content;
container image;
CompanyImage companyImage;
;
select companyImage;
image = companyImage.Image;
bin.setData(image);
content=bin.base64Encode();
AifUtil::saveBase64ToFile("c:\\temp\\test.tif", content);

How to read HtmlDocument in ASP.NET?

i have an aspx page,there is textbox to write an url and a button to show some pictures that are in that url.I can load the url's source code to HtmlDocument.but i dont know how to load pictures from that html source code to show that pictures in my page.How can i do that ? Thanks in advance
You need to make the question more clear so that one can give you a specific answer.
HTML is a markup language which means that there are only format tags, there are no pictures embedded in a .html document. There are only links to images that are urls that can be accessed trough some address. In order to get the images you need to get that url.
If your question is how you can get the actual html from a link then refer to the following question. But, since you say that you can get the html, then you need to parse it using Regex or HTML Agility Pack.
Code to get the image:
byte[] imageData = DownloadData(Url); //DownloadData function from here
MemoryStream stream = new MemoryStream(imageData);
Image img = Image.FromStream(stream);
stream.Close();
for method DownloadData you can use WebClient or WebRequest to get the image in a byte array:
WebRequest req = WebRequest.Create("[URL here]");
WebResponse response = req.GetResponse();
Stream stream = response.GetResponseStream();
byte[] b;
using (BinaryReader br = new BinaryReader(stream))
{
b = br.ReadBytes(size);
br.Close();
}
return b;

Why does Image.FromFile keep a file handle open sometimes?

I am doing a lot of image processing in GDI+ in .NET in an ASP.NET application.
I frequently find that Image.FromFile() is keeping a file handle open.
Why is this? What is the best way to open an image without the file handle being retained.
NB: I'm not doing anything stupid like keeping the Image object lying around - and even if I was I woudlnt expect the file handle to be kept active
I went through the same journey as a few other posters on this thread. Things I noted:
Using Image.FromFile does seem unpredictable on when it releases the file handle. Calling the Image.Dispose() did not release the file handle in all cases.
Using a FileStream and the Image.FromStream method works, and releases the handle on the file if you call Dispose() on the FileStream or wrap the whole thing in a Using {} statement as recommended by Kris. However if you then attempt to save the Image object to a stream, the Image.Save method throws an exception "A generic error occured in GDI+". Presumably something in the Save method wants to know about the originating file.
Steven's approach worked for me. I was able to delete the originating file with the Image object in memory. I was also able to save the Image to both a stream and a file (I needed to do both of these things). I was also able to save to a file with the same name as the originating file, something that is documented as not possible if you use the Image.FromFile method (I find this weird since surely this is the most likely use case, but hey.)
So to summarise, open your Image like this:
Image img = Image.FromStream(new MemoryStream(File.ReadAllBytes(path)));
You are then free to manipulate it (and the originating file) as you see fit.
I have had the same problem and resorted to reading the file using
return Image.FromStream(new MemoryStream(File.ReadAllBytes(fileName)));
Image.FromFile keeps the file handle open until the image is disposed. From the MSDN:
"The file remains locked until the Image is disposed."
Use Image.FromStream, and you won't have the problem.
using(var fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
return Image.FromStream(fs);
}
Edit: (a year and a bit later)
The above code is dangerous as it is unpredictable, at some point in time (after closing the filestream) you may get the dreaded "A generic error occurred in GDI+". I would amend it to:
Image tmpImage;
Bitmap returnImage;
using(var fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
tmpImage = Image.FromStream(fs);
returnImage = new Bitmap(tmpImage);
tmpImage.Dispose();
}
return returnImage;
Make sure you are Disposing properly.
using (Image.FromFile("path")) {}
The using expression is shorthand for
IDisposable obj;
try { }
finally
{
obj.Dispose();
}
#Rex in the case of Image.Dispose it calls GdipDisposeImage extern / native Win32 call in it's Dispose().
IDisposable is used as a mechanism to free unmanaged resources (Which file handles are)
I also tried all your tips (ReadAllBytes, FileStream=>FromStream=>newBitmap() to make a copy, etc.) and they all worked. However, I wondered, if you could find something shorter, and
using (Image temp = Image.FromFile(path))
{
return new Bitmap(temp);
}
appears to work, too, as it disposes the file handle as well as the original Image-object and creates a new Bitmap-object, that is independent from the original file and therefore can be saved to a stream or file without errors.
I would have to point my finger at the Garbage Collector. Leaving it around is not really the issue if you are at the mercy of Garbage Collection.
This guy had a similar complaint... and he found a workaround of using a FileStream object rather than loading directly from the file.
public static Image LoadImageFromFile(string fileName)
{
Image theImage = null;
fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
{
byte[] img;
img = new byte[fileStream.Length];
fileStream.Read(img, 0, img.Length);
fileStream.Close();
theImage = Image.FromStream(new MemoryStream(img));
img = null;
}
...
It seems like a complete hack...
As mentioned above the Microsoft work around causes a GDI+ error after several images have been loaded. The VB solution for me as mentioned above by Steven is
picTemp.Image = Image.FromStream(New System.IO.MemoryStream(My.Computer.FileSystem.ReadAllBytes(strFl)))
I just encountered the same problem, where I was trying to merge multiple, single-page TIFF files into one multipart TIFF image. I needed to use Image.Save() and 'Image.SaveAdd()`: https://msdn.microsoft.com/en-us/library/windows/desktop/ms533839%28v=vs.85%29.aspx
The solution in my case was to call ".Dispose()" for each of the images, as soon as I was done with them:
' Iterate through each single-page source .tiff file
Dim initialTiff As System.Drawing.Image = Nothing
For Each filePath As String In srcFilePaths
Using fs As System.IO.FileStream = File.Open(filePath, FileMode.Open, FileAccess.Read)
If initialTiff Is Nothing Then
' ... Save 1st page of multi-part .TIFF
initialTiff = Image.FromStream(fs)
encoderParams.Param(0) = New EncoderParameter(Encoder.Compression, EncoderValue.CompressionCCITT4)
encoderParams.Param(1) = New EncoderParameter(Encoder.SaveFlag, EncoderValue.MultiFrame)
initialTiff.Save(outputFilePath, encoderInfo, encoderParams)
Else
' ... Save subsequent pages
Dim newTiff As System.Drawing.Image = Image.FromStream(fs)
encoderParams = New EncoderParameters(2)
encoderParams.Param(0) = New EncoderParameter(Encoder.Compression, EncoderValue.CompressionCCITT4)
encoderParams.Param(1) = New EncoderParameter(Encoder.SaveFlag, EncoderValue.FrameDimensionPage)
initialTiff.SaveAdd(newTiff, encoderParams)
newTiff.Dispose()
End If
End Using
Next
' Make sure to close the file
initialTiff.Dispose()

Resources