I am trying to convert a PDF page to an image, to create thumbnails. This is the code that I am using:
PdfRenderer pdfRenderer = new PdfRenderer(GetSeekableFileDescriptor(filePath));
var appDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
string directoryPath = System.IO.Path.Combine(appDirectory, "thumbnailsTemp", System.IO.Path.GetFileNameWithoutExtension(fileName));
if (!Directory.Exists(directoryPath))
{
Directory.CreateDirectory(directoryPath);
int pageCount = pdfRenderer.PageCount;
for (int i = 0; i < pageCount; i++)
{
Page page = pdfRenderer.OpenPage(i);
Android.Graphics.Bitmap bmp = Android.Graphics.Bitmap.CreateBitmap(page.Width, page.Height, Android.Graphics.Bitmap.Config.Rgb565 or Argb8888);
page.Render(bmp, null, null, PdfRenderMode.ForDisplay);
try
{
using (FileStream output = new FileStream(System.IO.Path.Combine(directoryPath, fileName + "Thumbnails" + i + ".png"), FileMode.Create))
{
bmp.Compress(Android.Graphics.Bitmap.CompressFormat.Png, 100, output);
}
page.Close();
}
catch (Exception ex)
{
//TODO -- GERER CETTE EXPEXPTION
throw new Exception();
}
}
return directoryPath;
}
I tried with ARGB 8888 and that was a success. But the rendering time was too slow for big PDF files. This is why I tried to improve it by changing the format to RGB 565. But my app is crashing with this Execption:
Unsuported pixel format
Any idea to fix this, or how to render a PDF to a bitmap faster? I was looking on google but didn't find a solution related to my code.
UPDATE
I did this but know, my app is crashing at this line of code :
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
My class :
public async Task<string> GetBitmaps(string filePath)
{
//TODO -- WORK ON THIS
PdfRenderer pdfRenderer = new PdfRenderer(GetSeekableFileDescriptor(filePath));
var appDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
string directoryPath = System.IO.Path.Combine(appDirectory, "thumbnailsTemp", System.IO.Path.GetFileNameWithoutExtension(fileName));
var stream = new MemoryStream();
using (Stream resourceStream = new FileStream(filePath, FileMode.Open))
{
resourceStream.CopyTo(stream);
}
for (int i = 0; i < pdfRenderer.PageCount; i++)
{
TallComponents.PDF.Rasterizer.Page page = new TallComponents.PDF.Rasterizer.Page(stream, i);
byte[] bytes = null;
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
using (FileStream output = new FileStream(System.IO.Path.Combine(directoryPath, fileName + "Thumbnails" + i + ".png"), FileMode.Create, FileAccess.Write))
{
output.Write(bytes, 0, bytes.Length);
}
}
return directoryPath;
}
you could draw a PDF page in app by converting a PDF page to a bitmap,here the PDF document itself is embedded as a resource.
var assembly = Assembly.GetExecutingAssembly();
var stream = new MemoryStream();
using (Stream resourceStream = assembly.GetManifestResourceStream("DrawPdf.Android.tiger.pdf"))
{
resourceStream.CopyTo(stream);
}
Page page = new Page(stream, 0);
// render PDF Page object to a Bitmap
byte[] bytes = null;
await Task.Run(() =>
{
bytes = page.AsPNG(72);
});
Bitmap bmp = global::Android.Graphics.BitmapFactory.DecodeByteArray(bytes, 0, bytes.Length);
Related
I am writing a Windows 10 Store app. In the app the User can input a Text, and then press "Read Text" and Cortana reads the text loud. That works fine.
Now I want to add the feature, to press a button called "Save" or something like that and then save Cortanas output as mp3 file. This should work via a normal save-file dialog.
This is what I got so far.
private static MediaElement mediaplayer = new MediaElement();
/// ... mediaplayer element gets content ...
Uri file = mediaplayer.Source;
Instead of an Uri element I could also get an SpeechSynthesisStream with this information.
How can I save this Uri / Stream to a file?
EDIT:
this is the final code:
var stream2 = stream.CloneStream();
//... use stream2 as mediaelement ...
if(stream != null)
{
using (var reader = new DataReader(stream))
{
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
savePicker.FileTypeChoices.Add("WAV", new List<string>() { ".wav" });
savePicker.SuggestedFileName = "sound.wav";
StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
{
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (var writer = new DataWriter(outputStream.GetOutputStreamAt(0)))
{
long writtenBytes = 0;
const int bufferSize = 8192;
uint loadedBytes = 0;
while ((loadedBytes = (await reader.LoadAsync(bufferSize))) > 0) //!!!
{
IBuffer buffer = reader.ReadBuffer(loadedBytes);
writer.WriteBuffer(buffer);
uint tmpWritten = await writer.StoreAsync(); //!!!
writtenBytes += tmpWritten;
}
}
}
}
}
}
If you're trying to write the output to a file instead (or as well as) rendering it audibly to a MediaElement, you probably want something like this in here as well.
SpeechSynthesisStream synthesisStream = await synthesizer.SynthesizeTextToStreamAsync(text);
var stream2 = synthesisStream.CloneStream();
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.MusicLibrary;
savePicker.FileTypeChoices.Add("WAV", new List<string>() { ".wav" });
savePicker.SuggestedFileName = "sound.wav";
StorageFile file = await savePicker.PickSaveFileAsync();
using (var reader = new DataReader(synthesisStream))
{
using (var outputStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (var writer = new DataWriter(outputStream.GetOutputStreamAt(0)))
{
long writtenBytes = 0;
const int bufferSize = 8192;
uint loadedBytes = 0;
while ((loadedBytes = (await reader.LoadAsync(bufferSize))) > 0) //!!!
{
IBuffer buffer = reader.ReadBuffer(loadedBytes);
writer.WriteBuffer(buffer);
uint tmpWritten = await writer.StoreAsync(); //!!!
writtenBytes += tmpWritten;
}
}
}
}
// Set the source and start playing the synthesized audio stream.
media.AutoPlay = true;
media.SetSource(stream2, synthesisStream.ContentType);
media.Play();
The one problem is that the synthesisStream isn't rewindable (so far as I can tell), so you might have to synthesize it twice, or make a second (in memory) copy of the stream if you want to make it audible at the same time.
IArchive archive = null;
IReader reader = null;
archive = SevenZipArchive.Open(fileStream, Options.LookForHeader);
reader = archive.ExtractAllEntries();
while (reader.MoveToNextEntry())
{
if (!reader.Entry.IsDirectory)
{
Stream _redaer = new MemoryStream();
reader.WriteEntryTo(_redaer);
fileName = reader.Entry.FilePath;
int index = fileName.LastIndexOf("/");
string file = fileName.Substring(index + 1, (fileName.Length - (index + 1)));
using (binaryReader = new BinaryReader(_redaer, encoding))
{
long fileLength = _redaer.Length;
MemoryStream ms = new MemoryStream();
_redaer.Position = 0;
_redaer.CopyTo(ms);
byte[] buteArray = ms.ToArray();
SaveToIsoStore(fileName, buteArray);
}
}
}
This code gives exception of type SharpCompress.Common.InvalidFormatException,Please provide the solution in wp7.
I try to create a PDF report from a datatable. One of the columns contents image. How can I extract the image from datatable and insert into PDF table? I'm using iTextShap version 5.4.2.0. Here is the code:
public void Report(DataTable dt, string output)
{
Document doc = new Document(PageSize.LETTER, 50, 50, 80, 50);
PdfWriter PDFWriter = PdfWriter.GetInstance(doc, new FileStream(output, FileMode.Create));
PDFWriter.ViewerPreferences = PdfWriter.PageModeUseOutlines;
iTextSharp.text.Font hel8 = FontFactory.GetFont(BaseFont.HELVETICA, 8);
doc.Open();
PdfPTable table = new PdfPTable(dt.Columns.Count);
float[] widths = new float[] { 1.2f, 1.2f, 1.2f, 1.2f, 1f, 4f, 1f, 4f };
table.SetWidths(widths);
table.WidthPercentage = 100;
PdfPCell cell = new PdfPCell(new Phrase("NewCells"));
cell.Colspan = dt.Columns.Count;
foreach (DataColumn c in dt.Columns)
{
table.AddCell(new Phrase(c.ColumnName, hel8));
}
foreach (DataRow r in dt.Rows)
{
if (dt.Rows.Count > 0)
{
table.AddCell(new Phrase(r[0].ToString(), hel8));
table.AddCell(new Phrase(r[1].ToString(), hel8));
table.AddCell(new Phrase(r[2].ToString(), hel8));
table.AddCell(new Phrase(r[3].ToString(), hel8));
table.AddCell(new Phrase(r[4].ToString(), hel8));
table.AddCell(new Phrase(r[5].ToString(), hel8));
byte[] byt = (byte[])r[6];
MemoryStream ms = new MemoryStream(byt);
System.Drwaing.Image sdi = System.Drawing.Image.FromStream(ms);
Image img = Image.GetInstance(sdi); <-- this is the problem code
table.AddCell(img);
table.AddCell(new Phrase(r[7].ToString(), hel8));
}
}
doc.Add(table);
}
doc.Close();
}
Update: #nekno, all of your suggestions are worked.
But I still need to correct the casting at line:
byte[] byt = (byte[])r[6];
It gave me a casting exception from VS2008. So I added the conversion function (pulled it from stackoverflow):
byte[] ImageToByte(System.Drawing.Image img)
{
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
img.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
return byteArray;
}
And revised the code:
byte[] byt = ImageToByte((System.Drawing.Image)dt.Rows[e][6]);
Thanks.
What exactly is the problem? What happens when you use your problem code?
Try one of the other Image.GetInstance() overloads:
You can pass the byte array directly:
byte[] byt = (byte[])r[6];
Image img = Image.GetInstance(byt);
Or you can pass the Stream:
byte[] byt = (byte[])r[6];
MemoryStream ms = new MemoryStream(byt);
Image img = Image.GetInstance(ms);
Or you can give iTextSharp more info about the image format:
byte[] byt = (byte[])r[6];
MemoryStream ms = new MemoryStream(byt);
System.Drawing.Image sdi = System.Drawing.Image.FromStream(ms);
Image img = Image.GetInstance(sdi, ImageFormat.Png);
If your column can be cast to a System.Drawing.Image, then you can use it directly:
Image img = Image.GetInstance((System.Drawing.Image)r[6], System.Drawing.Imaging.ImageFormat.Png);
I have suggested steps how shows how to add image into PDF, given below code snippet show how to add logo into your PDF using iTextsharp, follow provided below steps:
I have provided link to download "itextsharp" component from given link http://sourceforge.net/projects/itextsharp/
You have to add reference into your application.
Next you have to add required namespaces "iTextsharp.text.html", "iTextsharp.text" to consume its best properties.
Now you have to add code snippet into your application given at the end, add code snippet under "button click" in code behind.
Hope it will work for you !!!
protected void btnPDF_Click(object sender, ImageClickEventArgs e)
{
DataTable dtn = new DataTable();
dtn = GetDataTable();
dtPDF = dtn.Copy();
for (int i = 0; i <= dtn.Rows.Count - 1; i++)
{
ExportToPdf(dtPDF);
}
}
public void ExportToPdf(DataTable myDataTable)
{
Document pdfDoc = new Document(PageSize.A4, 10, 10, 10, 10);
try
{
PdfWriter.GetInstance(pdfDoc, System.Web.HttpContext.Current.Response.OutputStream);
pdfDoc.Open();
Chunk c = new Chunk("" + System.Web.HttpContext.Current.Session["CompanyName"] + "", FontFactory.GetFont("Verdana", 11));
Paragraph p = new Paragraph();
p.Alignment = Element.ALIGN_CENTER;
p.Add(c);
pdfDoc.Add(p);
string clientLogo = Server.MapPath(".") + "/logo/tpglogo.jpg";
string imageFilePath = Server.MapPath(".") + "/logo/tpglogo.jpg";
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(imageFilePath);
//Resize image depend upon your need
jpg.ScaleToFit(80f, 60f);
//Give space before image
jpg.SpacingBefore = 0f;
//Give some space after the image
jpg.SpacingAfter = 1f;
jpg.Alignment = Element.HEADER;
pdfDoc.Add(jpg);
Font font8 = FontFactory.GetFont("ARIAL", 7);
DataTable dt = myDataTable;
if (dt != null)
{
//Craete instance of the pdf table and set the number of column in that table
PdfPTable PdfTable = new PdfPTable(dt.Columns.Count);
PdfPCell PdfPCell = null;
for (int rows = 0; rows < dt.Rows.Count; rows++)
{
for (int column = 0; column < dt.Columns.Count; column++)
{
PdfPCell = new PdfPCell(new Phrase(new Chunk(dt.Rows[rows][column].ToString(), font8)));
PdfTable.AddCell(PdfPCell);
}
}
//PdfTable.SpacingBefore = 15f; // Give some space after the text or it may overlap the table
pdfDoc.Add(PdfTable); // add pdf table to the document
}
pdfDoc.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename= SampleExport.pdf");
System.Web.HttpContext.Current.Response.Write(pdfDoc);
Response.Flush();
Response.End();
//HttpContext.Current.ApplicationInstance.CompleteRequest();
}
catch (DocumentException de)
{
System.Web.HttpContext.Current.Response.Write(de.Message);
}
catch (IOException ioEx)
{
System.Web.HttpContext.Current.Response.Write(ioEx.Message);
}
catch (Exception ex)
{
System.Web.HttpContext.Current.Response.Write(ex.Message);
}
}
i get the stream from webSite ,then put it in isolatedStorage into IsolatedstorageStream ,
but it don't work ,no error no sound , what's wrong ????
HttpWebResponse reponse = request.EndGetResponse(result) as HttpWebResponse;
if (reponse.StatusCode == HttpStatusCode.OK)
{
Stream stream=reponse.GetResponseStream();
SaveMusic(stream, "music");
ReadMusic("music");
Deployment.Current.Dispatcher.BeginInvoke(
() =>
{
me.AutoPlay = true;
me.Volume = 100;
me.SetSource(songStream);
me.Play();
});
}
ok thanks keyboardP for your help ;here is my code
protected void SaveMusic(Stream stream,string name)
{
IsolatedStorageFile fileStorage = IsolatedStorageFile.GetUserStoreForApplication();
if (!fileStorage.DirectoryExists("Source/Music"))
{
fileStorage.CreateDirectory("Source/Music");
}
using (IsolatedStorageFileStream fileStream = IsolatedStorageFile.GetUserStoreForApplication().OpenFile("Source\\Music\\" + name + ".mp3", FileMode.Create))
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
fileStream.Write(bytes, 0, bytes.Length);
fileStream.Flush();
}
}
protected void ReadMusic(string name)
{
using (IsolatedStorageFile fileStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
songStream = null;
songStream = new IsolatedStorageFileStream("Source\\Music\\" + name + ".mp3", FileMode.Open, fileStorage);
}
}
Assuming your saving and reading code is correct, your stream's position might be at the end. Try adding
songStream.Position = 0;
before SetSource(songStream);
Try using this to save the file:
using (var fileStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
var buffer = new byte[1024];
using (var myIsStream = fileStorage.OpenFile("Source\\Music\\" + name + ".mp3", FileMode.CreateNew))
{
int bytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, 1024)) > 0)
myIsStream.Write(buffer, 0, bytesRead);
}
}
The below code which uses npoi to create excel documents displays images in open office calc but not in excel.
If i open the doc in calc and save the document and then open the document in excel i can then see the images in excel.
Here is the code.
public static byte[] CreateExcel(CampaignViewModel viewModel, string fileName)
{
byte[] output;
using (FileStream fs = new FileStream(HttpContext.Current.Server.MapPath(#"\Data\templates\NPOITemplate.xls"), FileMode.Open, FileAccess.ReadWrite))
{
var templateWorkbook = new HSSFWorkbook(fs, true);
var sheet = templateWorkbook.GetSheet("Sheet1");
var patriarch = sheet.CreateDrawingPatriarch();
var leftFieldHeaders = CsvHelper.GetMatrixAllLeftFields();
var productHeaders = CsvHelper.GetMatrixProducts(viewModel.ProductCampaigns);
var totalCols = leftFieldHeaders.Count + productHeaders.Count;
var colWidth = 5000;
for (int i = 0; i < totalCols; i++)
{
sheet.SetColumnWidth(i, colWidth);
}
var imageRow = sheet.CreateRow(0);
imageRow.Height = 2000;
var imageCellCount = 0;
foreach (var header in leftFieldHeaders)
{
imageRow.CreateCell(imageCellCount).SetCellValue("");
imageCellCount++;
}
foreach (var product in viewModel.ProductCampaigns)
{
try
{
var anchor = new HSSFClientAnchor(0, 0, 0, 0, imageCellCount, 0, imageCellCount, 0);
anchor.AnchorType = 2;
var path = HttpContext.Current.Server.MapPath(product.Product.ImageThumbUrl);
var picture = patriarch.CreatePicture(anchor, LoadImage(#path, templateWorkbook));
picture.Resize();
picture.LineStyle = HSSFPicture.LINESTYLE_SOLID;
}
catch (Exception)
{
}
imageCellCount++;
}
using (MemoryStream ms = new MemoryStream())
{
templateWorkbook.Write(ms);
output = ms.ToArray();
}
}
return output;
}
public static int LoadImage(string path, HSSFWorkbook wb)
{
try
{
var file = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
var buffer = new byte[file.Length];
file.Read(buffer, 0, (int)file.Length);
return wb.AddPicture(buffer, PictureType.JPEG);
}
catch (Exception)
{
return 0;
}
}
i've resolved the above in a round about way. Turns out i didn't really need to use the template and could just create the xls from scratch. This add's a bit more meta data to the file which i suspect was the issue
public static byte[] CreateExcel2(CampaignViewModel viewModel, ICollection<DeliveryPoint> deliveryPoints, string fileName)
{
FileContentResult fileContentResult;
byte[] output;
var matrixCampaignLines = viewModel.MatrixCampaignLines;
HSSFWorkbook hssfworkbook = new HSSFWorkbook();
DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company = "NPOI Team";
hssfworkbook.DocumentSummaryInformation = dsi;
////create a entry of SummaryInformation
SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
si.Subject = "NPOI SDK Example";
hssfworkbook.SummaryInformation = si;
var sheet = hssfworkbook.CreateSheet("Sheet1");
var patriarch = sheet.CreateDrawingPatriarch();
var leftFieldHeaders = (viewModel.Campaign.EnableNameOnCampaign) ? CsvHelper.GetMatrixAllLeftFields() : CsvHelper.GetMatrixAllLeftFieldsWithoutName();
var productHeaders = CsvHelper.GetMatrixProducts(viewModel.ProductCampaigns);
var totalCols = leftFieldHeaders.Count + productHeaders.Count;
var colWidth = 5000;
for (int i = 0; i < totalCols; i++)
{
sheet.SetColumnWidth(i, colWidth);
}
var imageRow = sheet.CreateRow(0);
imageRow.Height = 2000;
var imageCellCount = 0;
foreach (var header in leftFieldHeaders)
{
imageRow.CreateCell(imageCellCount).SetCellValue("");
imageCellCount++;
}
foreach (var product in viewModel.ProductCampaigns)
{
try
{
var anchor = new HSSFClientAnchor(0, 0, 0, 0, imageCellCount, 0, imageCellCount, 0);
anchor.AnchorType = 2;
var path = HttpContext.Current.Server.MapPath(product.Product.ImageThumbUrl);
var picture = patriarch.CreatePicture(anchor, LoadImage(#path, hssfworkbook));
picture.Resize();//Comment this line if your code crashes.
picture.LineStyle = HSSFPicture.LINESTYLE_SOLID; might not
}
catch (Exception)
{
}
imageCellCount++;
}
using (MemoryStream ms = new MemoryStream())
{
hssfworkbook.Write(ms);
output = ms.ToArray();
}
return output;
}
public static int LoadImage(string path, HSSFWorkbook wb)
{
try
{
var file = new FileStream(path, FileMode.Open, FileAccess.Read);
var buffer = new byte[file.Length];
file.Read(buffer, 0, (int)file.Length);
return wb.AddPicture(buffer, PictureType.JPEG);
}
catch (Exception)
{
return 0;
}
}
I got it right now.
I am using
try
{
ISheet sheet = templateWorkbook.GetSheet(sheetName);
HSSFPatriarch patriarch = (HSSFPatriarch)sheet.CreateDrawingPatriarch();
//create the anchor
HSSFClientAnchor anchor;
anchor = new HSSFClientAnchor(0, 0, 255, 255,
start.Col, start.Row, end.Col, end.Row);
anchor.AnchorType = 2;
patriarch.CreatePicture(anchor,
LoadImage(imagePath, templateWorkbook));
}
catch (IOException ioe)
{
}
and LoadImage() method which returns path from the server.
Use this one. It runs fine.