XF skiasharp downloads corrupted PDF - pdf

I want to create PDF reports using Xamarin Forms. I have tried creating sample PDF usin skiasharp plugin. But I am facing strange problem.
PDF can be opened in Mobile Device(Android 10.0, API 29) very easily. but if I try to open same PDF in laptop then it shows error message saying Can not open corrupted PDF.
Also if we look at size of the PDF, It is 183 KB in device and 0KB in laptop.
Code
private void GenerateDocument()
{
try
{
var root = EnsureTempDataDirectory("CreatePdfSample");
path = Path.Combine(root, $"{Guid.NewGuid():N}.pdf");
if (!isSupported || (isSupported && File.Exists(path)))
return;
var metadata = new SKDocumentPdfMetadata
{
Author = "Cool Developer",
Creation = DateTime.Now,
Creator = "Cool Developer Library",
Keywords = "SkiaSharp, Sample, PDF, Developer, Library",
Modified = DateTime.Now,
Producer = "SkiaSharp",
Subject = "SkiaSharp Sample PDF",
Title = "Sample PDF",
};
var stream = SKFileWStream.OpenStream(path);
var document = SKDocument.CreatePdf(path, metadata);
if (document == null)
{
isSupported = false;
return;
}
var paint = new SKPaint
{
TextSize = 64.0f,
IsAntialias = true,
Color = 0xFF9CAFB7,
IsStroke = true,
StrokeWidth = 3,
TextAlign = SKTextAlign.Center
};
var pageWidth = 840;
var pageHeight = 1188;
// draw page 1
using (var pdfCanvas = document.BeginPage(pageWidth, pageHeight))
{
// draw button
var nextPagePaint = new SKPaint
{
IsAntialias = true,
TextSize = 16,
Color = SKColors.OrangeRed
};
var nextText = "Next Page >>";
var btn = new SKRect(pageWidth - nextPagePaint.MeasureText(nextText) - 24, 0, pageWidth, nextPagePaint.TextSize + 24);
pdfCanvas.DrawText(nextText, btn.Left + 12, btn.Bottom - 12, nextPagePaint);
// make button link
pdfCanvas.DrawLinkDestinationAnnotation(btn, "next-page");
// draw contents
pdfCanvas.DrawText("...PDF 1/2...", pageWidth / 2, pageHeight / 4, paint);
document.EndPage();
}
// draw page 2
using (var pdfCanvas = document.BeginPage(pageWidth, pageHeight))
{
// draw link destintion
pdfCanvas.DrawNamedDestinationAnnotation(SKPoint.Empty, "next-page");
// draw contents
pdfCanvas.DrawText("...PDF 2/2...", pageWidth / 2, pageHeight / 4, paint);
document.EndPage();
}
// end the doc
document.Close();
}
catch (Exception ex)
{
throw;
}
}
For sample, I have taken reference from Skiasharp Sample available on github.
Any help would be appreciated
Edit
As I have Created folder named CreatePDFSample, path of the file is
/Internal Storage/Download/CreatePdfSample/8c134318ca8d49f59d7a57e244845107.pdf
One more thing I noted right now, One of the 10-12 files I have created is opening in laptop as well. It is also at the same path. I can't understand what might be issue here.
Thanks

I had not disposed of the stream correctly. The using keyword for stream solved the issue.

Related

Extract the center-aligned lines from a PDF document using itext7 in C#.Net application

anybody help me extract the center-aligned lines from a PDF document using itext7 in .Net Core application.
I have written the following extraction code so far, but cannot get the lines that are center aligned. Is there any way, please help
private async Task Extruct()
{
_pdfFile = await UploadedFilesService.GetUploadedPdfById(entryId);
MemoryStream stream = new MemoryStream(_pdfFile);
using (PdfReader pdfReader = new PdfReader(stream))
{
using (PdfDocument pdfDocument = new PdfDocument(pdfReader))
{
for (int i = 1; i <= pdfDocument.GetNumberOfPages(); i++)
{
PdfPage page = pdfDocument.GetPage(i);
string pageText = PdfTextExtractor.GetTextFromPage(page);
string[] lineTexts = pageText.Split('\n');
foreach (string lineText in lineTexts)
{
float lineWidth = lineText.Length;
float pageWidth = page.GetPageSize().GetWidth();
if ((pageWidth / 2 - lineWidth * 10) > 20)
{
persons.Add(lineText);
}
}
}
extracted = true;
}
}
this.StateHasChanged();
}

Extendscript with Photoshop: Importing an image

I'm trying to select some image files via a prompt, then add those files to the active document. Here's what I have so far:
#target photoshop
doc = app.activeDocument;
// choose image files
var files = File.openDialog(undefined,undefined,true);
// for each image, add to new layer and insert into doc
for (var file in files) {
var layer = doc.artLayers.add();
layer.image = file; // this doesn't work.
}
What's layer.image? ArtLayer doesn't have this property. Maybe placing will work better in your case:
doc = app.activeDocument;
// choose image files
var files = File.openDialog(undefined, undefined, true);
// for each image, add to new layer and insert into doc
for (var i = 0; i < files.length; i++)
{
var layer = placeImage(files[i]);
}
function placeImage(imageFile)
{
var desc554 = new ActionDescriptor();
desc554.putPath(cTID('null'), imageFile);
desc554.putEnumerated(cTID('FTcs'), cTID('QCSt'), cTID('Qcsa'));
var desc555 = new ActionDescriptor();
desc555.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), 0.000000);
desc555.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), 0.000000);
desc554.putObject(cTID('Ofst'), cTID('Ofst'), desc555);
executeAction(cTID('Plc '), desc554, DialogModes.NO);
return activeDocument.activeLayer
};
function cTID(s)
{
return app.charIDToTypeID(s);
};
function sTID(s)
{
return app.stringIDToTypeID(s);
};
Also Photoshop doesn't like when for...in loops are used on Array (sometimes it works, sometimes it doesn't: in case of File object it doesn't work)

Screenshot using SharpDX and EasyHook transparent

I have been struggling in taking screenshots with DirectX, the problem is, it's working but seems to be missing some colors (black outline is missing for example), and some stuff that is also rendered by DX doesn't show.
I have uploaded the images (how the image should render and the rendered one) and also the code, what might be the issue?
Correct Image
Rendered Image
Greetings
public class Screenshot
{
public static void TakeScreenshot(string name = null)
{
var t = new Thread((ThreadStart) delegate
{
// destination folder
var destinationFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments, Environment.SpecialFolderOption.Create) + "\\My Software\\Screenshots";
if (!Directory.Exists(destinationFolder)) Directory.CreateDirectory(destinationFolder);
// file name
string filename = name;
if (string.IsNullOrEmpty(name))
filename = "image-" + (Directory.GetFiles(destinationFolder, "*.png").Count() + 1).ToString("000") + ".png";
// # of graphics card adapter
const int numAdapter = 0;
// # of output device (i.e. monitor)
const int numOutput = 0;
// Create DXGI Factory1
var factory = new Factory1();
var adapter = factory.GetAdapter1(numAdapter);
// Create device from Adapter
var device = new Device(adapter);
// Get DXGI.Output
var output = adapter.GetOutput(numOutput);
var output1 = output.QueryInterface<Output1>();
// Width/Height of desktop to capture
int width = ((SharpDX.Rectangle)output.Description.DesktopBounds).Width;
int height = ((SharpDX.Rectangle)output.Description.DesktopBounds).Height;
// Create Staging texture CPU-accessible
var textureDesc = new Texture2DDescription
{
CpuAccessFlags = CpuAccessFlags.Read,
BindFlags = BindFlags.None,
Format = Format.B8G8R8A8_UNorm,
Width = width,
Height = height,
OptionFlags = ResourceOptionFlags.None,
MipLevels = 1,
ArraySize = 1,
SampleDescription = { Count = 1, Quality = 0 },
Usage = ResourceUsage.Staging
};
var screenTexture = new Texture2D(device, textureDesc);
// Duplicate the output
var duplicatedOutput = output1.DuplicateOutput(device);
bool captureDone = false;
for (int i = 0; !captureDone; i++)
{
try
{
SharpDX.DXGI.Resource screenResource;
OutputDuplicateFrameInformation duplicateFrameInformation;
// Try to get duplicated frame within given time
duplicatedOutput.AcquireNextFrame(10000, out duplicateFrameInformation, out screenResource);
if (i > 0)
{
// copy resource into memory that can be accessed by the CPU
using (var screenTexture2D = screenResource.QueryInterface<Texture2D>())
device.ImmediateContext.CopyResource(screenTexture2D, screenTexture);
// Get the desktop capture texture
var mapSource = device.ImmediateContext.MapSubresource(screenTexture, 0, MapMode.Read, MapFlags.None);
// Create Drawing.Bitmap
var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
var boundsRect = new System.Drawing.Rectangle(0, 0, width, height);
// Copy pixels from screen capture Texture to GDI bitmap
var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
var sourcePtr = mapSource.DataPointer;
var destPtr = mapDest.Scan0;
for (int y = 0; y < height; y++)
{
// Copy a single line
Utilities.CopyMemory(destPtr, sourcePtr, width * 4);
// Advance pointers
sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
destPtr = IntPtr.Add(destPtr, mapDest.Stride);
}
// Release source and dest locks
bitmap.UnlockBits(mapDest);
device.ImmediateContext.UnmapSubresource(screenTexture, 0);
// Save the output
bitmap.Save(destinationFolder + Path.DirectorySeparatorChar + filename);
// Send Message
Main.Chat.AddMessage(null, "~b~Screenshot saved as " + filename);
// Capture done
captureDone = true;
}
screenResource.Dispose();
duplicatedOutput.ReleaseFrame();
}
catch (SharpDXException e)
{
if (e.ResultCode.Code != SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code)
{
throw e;
}
}
}
});
t.IsBackground = true;
t.Start();
}
}

How to write a script that does "Save for web" for mutiple resolutions in Adobe Illustrator?

It's tedious to have to click to "Save for web" and change the resolution each time I want to create the image as a different resolution. Is there a way to write a script to automatically achieve this, for multiple resolutions as one?
For that i myself use this function
function saveDocumentAsPng(d, width, height) {
var fileName = d.fullName.toString();
if(fileName.lastIndexOf(".") >= 0) { fileName = fileName.substr(0, fileName.lastIndexOf("."));}
fileName += "_wxh.png".replace("w", width).replace("h", height);
var exportOptions = new ExportOptionsPNG24();
exportOptions.horizontalScale = exportOptions.verticalScale = 100 * Math.max(width/d.width, height/d.height);
var file = new File(fileName);
app.activeDocument = d;
d.exportFile(file, ExportType.PNG24, exportOptions);
}
Note that it names a resulting png's with “_[width]x[height]” suffix.
I wrote my function based on a sample from adobe's javascript reference http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/illustrator/scripting/illustrator_scripting_reference_javascript_cs5.pdf (page 59).
This is an old post, but it inspired me to create a different version for my Android project that I'd like to share.
Just create a 144x144 pixels document and run this:
var doc = app.activeDocument;
// This is the scale factor that you can see in "Percent" textbox of
// the "Save for Web..." dialog box while changing the size of the image
var scale = [100, 66.67, 50, 33.33]
// This is the image size for the PNGs files names
var size = [144, 96, 72, 48]
for(var i = 0; i<4; i++)
{
var fileName = doc.fullName.toString();
if (fileName.lastIndexOf(".") >= 0) {
// Get the file name without the extension
fileName = fileName.substr(0, fileName.lastIndexOf("."));
}
// Name each file with yours size to avoid overwrite
fileName += "_wxh.png".replace("w", size[i]).replace("h", size[i]);
var exportOptions = new ExportOptionsPNG24();
exportOptions.horizontalScale = exportOptions.verticalScale = scale[i];
exportOptions.artBoardClipping = true;
var file = new File(fileName);
doc.exportFile(file, ExportType.PNG24, exportOptions);
}
Window.alert ("Successfully exported!", "Success");
Thank you!
Here is the script that will export all files of the selected folder into PNG. You can specify resolution in this code and image quality will be good. In this code by default resolution is 600
var folder = Folder.selectDialog();
if (folder) {
var files = folder.getFiles("*.ai");
for (var i = 0; i < files.length; i++) {
var currentFile = files[i];
app.open(currentFile);
var activeDocument = app.activeDocument;
var pngFolder = Folder(currentFile.path + "/PNG");
if (!pngFolder.exists)
pngFolder.create();
var fileName = activeDocument.name.split('.')[0] + ".png";
var destinationFile = File(pngFolder + "/" + fileName);
// Export Artboard where you can set resolution for an image. Set to 600 by default in code.
var opts = new ImageCaptureOptions();
opts.resolution = 600;
opts.antiAliasing = true;
opts.transparency = true;
try {
activeDocument.imageCapture(new File(destinationFile), activeDocument.geometricBounds, opts);
} catch (e) {
}
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
currentFile = null;
}
}
If you want to export in jpg format, just change extension of the file in the code in the following line
var fileName = activeDocument.name.split('.')[0] + ".png";
change to
var fileName = activeDocument.name.split('.')[0] + ".jpg"; // For jpg
Also, you can change the name of the file and where the exported file will be stored according to your requirement.
Hope my answer will help you.

How can I copy annotations/highlighting from one PDF to an updated version of that PDF?

I've recently moved to almost exclusively electronic books. I prefer to mark up documents with highlighting or annotations as I read them.
However, when I get an updated version of a PDF - O'Reilly, for example, will give access to corrected versions of the books you've purchased - I'm then stuck with a marked up older copy and a newer copy, without my notes.
My preferred language being C# I realize that iTextSharp is probably what I'd need to use if I wanted to programmatically do this (see for example Copy pdf annotations via C#), but is there an easier way to handle this?
I can't believe I'm the only one with this issue, so is there perhaps already a solution that will handle this for me?
You can use this example for iTextSharp to approach your problem:
var output = new MemoryStream();
using (var document = new Document(PageSize.A4, 70f, 70f, 20f, 20f))
{
var readers = new List<PdfReader>();
var writer = PdfWriter.GetInstance(document, output);
writer.CloseStream = false;
document.Open();
const Int32 requiredWidth = 500;
const Int32 zeroBottom = 647;
const Int32 left = 50;
Action<String, Action> inlcudePdfInDocument = (filename, e) =>
{
var reader = new PdfReader(filename);
readers.Add(reader);
var pageCount = reader.NumberOfPages;
for (var i = 0; i < pageCount; i++)
{
e?.Invoke();
var imp = writer.GetImportedPage(reader, (i + 1));
var scale = requiredWidth / imp.Width;
var height = imp.Height * scale;
writer.DirectContent.AddTemplate(imp, scale, 0, 0, scale, left, zeroBottom - height);
var annots = reader.GetPageN(i + 1).GetAsArray(PdfName.ANNOTS);
if (annots != null && annots.Size != 0)
{
foreach (var a in annots)
{
var newannot = new PdfAnnotation(writer, new Rectangle(0, 0));
var annotObj = (PdfDictionary) PdfReader.GetPdfObject(a);
newannot.PutAll(annotObj);
var rect = newannot.GetAsArray(PdfName.RECT);
rect[0] = new PdfNumber(((PdfNumber)rect[0]).DoubleValue * scale + left); // Left
rect[1] = new PdfNumber(((PdfNumber)rect[1]).DoubleValue * scale); // top
rect[2] = new PdfNumber(((PdfNumber)rect[2]).DoubleValue * scale + left); // right
rect[3] = new PdfNumber(((PdfNumber)rect[3]).DoubleValue * scale); // bottom
writer.AddAnnotation(newannot);
}
}
document.NewPage();
}
}
foreach (var apprPdf in pdfs)
{
document.NewPage();
inlcudePdfInDocument(apprPdf.Pdf, null);
}
document.Close();
readers.ForEach(x => x.Close());
}
output.Position = 0;
return output;
This example copies a list of pdf files with annotations into a new pdf file.
Obtain data from two PdfReaders simultaneously - one for copying new pdf and another for copying annotations from old pdf.