Reduced in resolution when converting from Visio to PDF in Visio 2013 - office-interop

I have a .NET application that converts Visio files to PDF using the Document.ExportAsFixedFormat method. This works fine in Visio 2010.
However, upon upgrading to Visio 2013, the exact same code is producing PDF with much lower resolution that is unsuitable for print.
I am not sure what is wrong.
Is there something I can do to export high resolution PDF with Visio 2013?
Thanks!
The following is my code:
_app.ActiveDocument.ExportAsFixedFormat(VisFixedFormatTypes.visFixedFormatPDF, // Format
pdfpath, // Output path
VisDocExIntent.visDocExIntentPrint, // Output quality
VisPrintOutRange.visPrintFromTo, // Range
1, // Start page
-1, // End page
false, // Color as black
true, // Include background
false, // Include document properties
false, // Indicate tag structure
true, // Use ISO 19005-1 (PDF/A).
System.Reflection.Missing.Value // FixedFormatExtClass
);

Related

MS Powerpoint Addin : Insert Slide from Base 64 Powerpoint addin API does not carry over the original formatting of the slide

https://learn.microsoft.com/en-us/javascript/api/powerpoint/powerpoint.presentation?view=powerpoint-js-preview#powerpoint-powerpoint-presentation-insertslidesfrombase64-member(1)
I'm currently using the above Powerpoint Addin API to insert slides from base 64. But the inserted slide doesn't seem to carry over all the original formatting from the original PPTX file(from which the base 64 string was created). Any ideas on why the original formatting wasn't applied during insert?
PowerPoint.run(function (context) {
return context.sync.then(function(){
context.presentation.insertSlidesFromBase64(base64String),{
formatting: 'KeepSourceFormatting'
};
return context.sync()
})
});

itext7 PdfButtonFormField setImage method does not work on a signed pdf

I am using itext7 java library as shown below to add PdfButtonFormField to an existing pdf :
String src = "sample.pdf";
String dest = "acro_sample_empty_fields.pdf";
PdfDocument pdf = new PdfDocument(new PdfReader(src), new PdfWriter(dest));
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
PdfButtonFormField button = PdfFormField.createPushButton(pdf, new Rectangle(Integer.parseInt(control.xCord), Integer.parseInt(control.yCord),Integer.parseInt(control.width), Integer.parseInt(control.height)), control.name, control.value);
form.addField(button, page);
String resource = "sample.png";
button.setImage(resource);
After this i use the following code to fill the form like below :
String src = "1540982441_313554925_acro_sample_empty_fields_signedFinal.pdf";
String dest = "acro_sample_filled_fields.pdf";
PdfReader reader = new PdfReader(src);
File output = new File(dest);
OutputStream outputStream = new FileOutputStream(output);
PdfDocument document = new PdfDocument(reader,
new PdfWriter(outputStream),
new StampingProperties().useAppendMode());
PdfAcroForm form = PdfAcroForm.getAcroForm(document, true);
Map<String, PdfFormField> fields = form.getFormFields();
String resource = "sample_test.png";
((PdfButtonFormField)fields.get(control.name)).setImage(resource);
Everything works fine for a normal pdf. But if i digitally sign the created pdf and then try to fill it. then the image is not set properly.
For a normal pdf the image on the push button is changed as expected. But on the digitally signed pdf the image is not set.
I have tried looking for this on google but no luck yet. Any help will be appreciated. Thanks in advance.
I tested the code in this answer with the signed but unfilled PDF you shared. As you didn't share a sample image, though, I used one of my own.
A more precise observation
You say
Everything works fine for a normal pdf. But if i digitally sign the created pdf and then try to fill it. then the image is not set properly. For a normal pdf the image on the push button is changed as expected. But on the digitally signed pdf the image is not set.
This is not entirely true, the image is set but not all PDF viewers show it.
In detail: If you set the image in the signed PDF using your code, Adobe Reader indeed shows merely a grey box
but other PDF viewers, e.g. Foxit or Chrome's built-in viewer, do show the replacement image
Thus, the image is set for the digitally signed PDF, too. The actual problem is that Adobe Reader does not display it!
The cause
After some analysis and having followed some red herrings, the cause of the problem appears to be that if Adobe Reader displays a PDF with a changed AcroForm button appearance and
the PDF is not signed, then Adobe Reader simply uses the updated appearance stream; but if
the PDF is signed, then Adobe Reader tries to ignore the updated appearance stream and construct a new appearance from appearance characteristics information.
(Other PDF viewers, though, appear to always use the updated appearance stream.)
iText does create an appearance characteristics dictionary for the button (so Adobe Reader assumes it can ignore the updated appearance and can construct an new one based on this dictionary) but unfortunately does not add some button specific information to it, neither when constructing the button nor when changing the button. This in particular concerns the following two entries:
I
stream
(Optional; push-button fields only; shall be an indirect reference) A form XObject defining the widget annotation’s normal icon, which shall be displayed when it is not interacting with the user.
TP
integer
(Optional; push-button fields only) A code indicating where to position the text of the widget annotation’s caption relative to its icon:
0 No icon; caption only
1 No caption; icon only
2 Caption below the icon
3 Caption above the icon
4 Caption to the right of the icon
5 Caption to the left of the icon
6 Caption overlaid directly on the icon
Default value: 0.
(ISO 32000-2, Table 192 — Entries in an appearance characteristics dictionary)
As iText does not supply the TP value, the Default value kicks in and Adobe Reader creates a button appearance with "No icon; caption only". As no caption is defined, the result is a grey box.
A work-around
The most simple work-around is to remove the whole appearance characteristics dictionary during image update, i.e. replace
((PdfButtonFormField)fields.get(control.name)).setImage(resource);
by
PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
if (button.getPdfObject().containsKey(PdfName.MK)) {
button.setModified();
button.getPdfObject().remove(PdfName.MK);
}
(SetButtonImage helper method setLikeGautamAnandImproved)
Now Adobe Reader does not find any appearance characteristics and, therefore, cannot ignore the updated appearance stream.
A fix
Alternatively we can add the missing appearance characteristics entries, e.g. like this:
PdfButtonFormField button = (PdfButtonFormField)fields.get(control.name);
button.setImage(resource);
PdfWidgetAnnotation widget = button.getWidgets().get(0);
PdfDictionary characteristics = widget.getAppearanceCharacteristics();
if (characteristics != null) {
characteristics.setModified();
characteristics.put(PdfName.I, widget.getNormalAppearanceObject());
characteristics.put(PdfName.TP, new PdfNumber(1));
}
(SetButtonImage helper method setLikeGautamAnandImproved2)
The result looks slightly different, though:
As you see, there is a small frame around the image. Most likely you can make it vanish by setting other characteristics accordingly.

Win32 Toolbar Custom and Default icons on same bar

I realize win32 toolbar icon questions are common here, but none are relevant to my particular problem (most concern image lists, or associating with a bitmap handle).
I am trying to associate a toolbar button with an icon resource within my application. Since I am adding it to a toolbar that already has default images using TB_ADDBITMAP (new, open, save, etc), I cannot use an image list, as the article on MSDN says here:
The TB_SETIMAGELIST message cannot be combined with TB_ADDBITMAP. It also cannot be used with toolbars created with CreateToolbarEx, which calls TB_ADDBITMAP internally. When you create a toolbar with CreateToolbarEx or use TB_ADDBITMAP to add images, the toolbar manages the image list internally. Attempting to modify it with TB_SETIMAGELIST has unpredictable consequences.
MSDN says I should be able to use a resource directly with TB_ADDBITMAP, under the TBADDBITMAP::nID field:
If hInst is NULL, set this member to the bitmap handle of the bitmap with the button images. Otherwise, set it to the resource identifier of the bitmap with the button images.
The VS2008 resource editor shows a single 16x16 icon resource with the id IDI_ARROWLEFT. (I had a screenshot, but since I do not have enough "reputation" to post images you'll have to take my word for it)
This is clearly a valid icon as the following code makes the icon appear on the titlebar of the main window:
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_ARROWLEFT));
The problem is the resource icon is not appearing on the toolbar button within the window. Below is the sample code that is loading the resource and applying it to the toolbar button:
void populateToolbarTest()
{
int index = -1;
TBADDBITMAP tbab;
TBBUTTON tbb;
ZeroMemory(&tbab, sizeof(TBADDBITMAP));
ZeroMemory(&tbb, sizeof(TBBUTTON));
SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
tbab.hInst = hInst;
tbab.nID = IDI_ARROWLEFT;
// SendMessage returns 0 when testing
index = SendMessage(hWndToolbar, TB_ADDBITMAP, 1, (LPARAM)&tbab);
if (index == -1) return;
tbb.iBitmap = index;
tbb.fsState = TBSTATE_ENABLED;
tbb.fsStyle = TBSTYLE_BUTTON;
// result is set to 1 when testing
LRESULT result = SendMessage(hWndToolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbb);
}
This code successfully produces a button. However, there is no icon displayed, unlike with the defaults that I used in IDB_STD_SMALL_COLOR
I finally got it working. Turns out, it had nothing to do with the code.
Microsoft is EXTREMELY picky about the EXACT format of the image being referenced. It you use TB_ADDBITMAP with a custom image, it MUST be 256 colors, it MUST have the MS-Specific index format, and the only color I've gotten to register as transparent is black. I spent an hour in Photoshop messing with different formats and colors before figuring this out.
The clue was the CreateMappedBitmap function in the example on MSDN. The page on CreateMappedBitmap had this statement:
This function is fully supported only for images with color maps; that is, images with 256 or fewer colors.
What it doesn't mention is that this is true regardless of whether you use this function or not. I have tried each scenario with and without this helper function, as well as tried every other 256-color BMP index format. Some other formats managed to show up, but they were mangled.
Theoretically, you can use the CreateMappedBitmap COLORMAP to specify a transparency color other than black, but I'm not familiar enough with the "6 level RGB" format to know how to specify an exact color.
(ref: http://en.wikipedia.org/wiki/List_of_software_palettes#6_level_RGB)
Unless you're mixing custom icons with default ones, I would recommend sticking with TB_SETIMAGELIST. From what I've read, it's much more flexible (for example, it accepts more than 256 colors.)
(ref: Win32 Toolbars and 24bit Images)

How to see image data using opencv in visual studio?

I wrote an OPENCV project in VS2010 and the results were not the ones as I expected so I ran the debugger to see where is the problem. When I wanted to see the data inside the image loaded I didn't know how to do it so if I want to see the data inside my images what should I do?
It is pretty simple in matlab for seeing different channel of an image i.e.
a=imread('test.jpg');
p1 = a(:,:,1)
p2 = b(:,:,2)
.
.
In opencv I wrote the same thing but I don't know how to see all the element at once just like Matlab.
a= imread("test.jpg")
split(a,planes);
vector<Mat> T1;
T1 = planes[0];
// How can I see the data inside T1 when debugging the code ?
I think this is what you are looking for - it's a great Visual Studio add-on
https://bitbucket.org/sergiu/opencv-visualizers
Just download the installer, make sure VS is closed, run it, re-open VS and voila! Now, when you point to an OpenCV data structure, all kinds of nice info is showed.
Limitations: I saw some problems with multichannel images (it only shows the first channel) and it also has trouble displaying large matrices. If you want to see raw data in a big matrix, you can use the old good VS trick with debug variables: Stop at a breakpoint, go to Watch tab, and write there
((float*)myMat.data) ,10
Where float is the matrix type, myMat is your matrix, and 10 is the number of values you want to print. It will display the first 10 values at the memory location of myMat.data. If you do not correctly choose the data type, you'll see garbage. In my example, myMat is of type cv::Mat.
And never forget the power of visualizers:
imshow("Image", myMat);
If your data fits into an image. You can use the contrib module's colormap to enhance your visualizers.
I can't actually believe that nobody suggested Image Watch yet. It's the most amazing add-in ever. It shows you a view with all your Mat variables (images (gray and color), matrices) while debugging, there's useful stuff like zooming or contrast-stretching and you can even apply more complex functions directly in the plugin in real-time. It makes debugging of any kind of image operations a breeze and it's immensely helpful if you do calculations and linear algebra stuff with your cv::Mat matrices.
I recommend to use a NativeViewer extension. It actually displays the content of an image in a preview window, not only the properly formatted info.
If you don't want to use a plug-in or extension to Visual Studio, you can access the elements one by one in the debugging watch tab by typing this:
T1.data[T1.step.buf[0]*i + T1.step.buf[1]*j];
where i is the row you want to look at and j is the column.
after downloading imagewatch use the command in watch window
(imagesLoc._Myfirst)[0]
index of image in the vector
You can use the immediate window and the extenshion method like this one
/// <summary>
/// Displays image
/// </summary>
public static void Display (this Mat m, Rect rect = default, string windowName = "")
{
if (string.IsNullOrEmpty(windowName))
{
windowName = m.ToString();
}
var img = rect == default ? m : m.Crop(rect);
double coef = Math.Min(1600d / img.Width, 800d / img.Height);
Cv2.ImShow(windowName, img.Resize(new Size(coef * img.Width, (coef * img.Height) > 1 ? coef * img.Height : 1)));
Cv2.WaitKey();
}
Then you stop at a breakpoint and call yourImage.Display() in the immediate window.
If you can use CLion you can utilize the OpenCV Image Viewer plugin, which displays matrices while debugging just on click.
https://plugins.jetbrains.com/plugin/14371-opencv-image-viewer
Disclaimer: I'm an author of this plugin

DynamicPDF image quality loss

We are using a product called DynamicPDF to generate PDF's on the fly from dynamic data from a database. Their documentation says that their software leaves the image bytes intact and doesn't make any changes. Despite this, we have observed that the images we add seem to have quality loss on the resulting PDF output (at least that's how they look). So my question is what do I need to do with the DynamicPDF API to ensure that the image quality output is equal or close to what I put in?
We are using Version 5.1.2 Build 13650, below is the code that we use to add the image.
private void plcImageMain_LaidOut(object sender, PlaceHolderLaidOutEventArgs e)
{
if (e.LayoutWriter.RecordSets.Current.HasData)
{
string productId = e.LayoutWriter.RecordSets.Current["ProductId"].ToString();
string imgUrl = base.SetImageUrlParams(e.LayoutWriter.RecordSets.Current["ImageUrl"] as string, e.ContentArea.Width, e.ContentArea.Height);
System.Drawing.Bitmap bm = base.GetBitmap(imgUrl);
ceTe.DynamicPDF.PageElements.Image img = new ceTe.DynamicPDF.PageElements.Image(bm, 0, 0);
img.Height = e.ContentArea.Height;
img.Width = e.ContentArea.Width;
e.ContentArea.Add(img);
}
}
/// <summary>
/// Gets a bitmap from the requested image url
/// </summary>
/// <param name="imgCtrl"></param>
/// <param name="imgUrl"></param>
protected System.Drawing.Bitmap GetBitmap(string imgUrl)
{
// TODO: Add some validation to ensure the url is an image.
System.Net.WebRequest httpRequest = System.Net.HttpWebRequest.Create(imgUrl);
using (System.Net.HttpWebResponse httpResponse = httpRequest.GetResponse() as System.Net.HttpWebResponse)
using (Stream imgStream = httpResponse.GetResponseStream())
{
System.Drawing.Bitmap bm = System.Drawing.Bitmap.FromStream(imgStream) as System.Drawing.Bitmap;
return bm;
}
}
[Edit]
Here is the before and after screenshot.
[Edit]
Code using GetImage (why so slow?)
protected ceTe.DynamicPDF.Imaging.ImageData GetImageData(string imgUrl)
{
ImageData imgData = null;
using (System.Net.WebClient wc = new System.Net.WebClient())
{
imgData = ImageData.GetImage(wc.DownloadData(imgUrl));
}
return imgData;
}
GetImageData ("http://s7d2.scene7.com/is/image/SwissArmy/cm_vm_53900E--111mm_sol_front_a?fmt=jpeg&wid=400&hei=640");
All right, this looks like poor effort at resizing but it could just as well be your Acrobat reader doing it on screen, with the actual data being perfectly fine.
You should be able to select an image by clicking it in Reader (so it's highlighted blue) and then copy and paste it to an image editing program of your choice. That way, you should get the resource in original solution no matter what it's scaled down to.
There are also tools to extract images and other resources from PDFs, but I don't know one I can recommend offhand.
In regards to the DynamicPDF product, there is not any resizing or resampling done to the image as it is added to the PDF document. Pekka is actually right on with this. It is the reader that is visually representing the image with differing clarity (at different zoom levels).
If you are able to pull the image out of the PDF (as Pekka recommends above) you will see the image data is completely original and not modified.
One additional thing you can do to demonstrate this would be to take your original image, right click on it and select "Convert To Adobe PDF" (requires full Acrobat Pro). In that newly created PDF you would also visually see the same results.
One final thing worth noting is just a smalll inefficiency in the code you displayed above. Right now you are pulling the image content as a Stream, creating a bitmap out of that Stream object and then using that bitmap to create the DynamicPDF Image object. The recommended way to accomplish this would be to take the Stream object of the image that you are pulling from the URL, pass this into the DynamicPDF's ImageData Static method "GetImage". This GetImage method will return the ImageData object. Then use that ImageData to create your DynamicPDF Image object out of.
There are two clear advantages to loading the image this way. First is that you do not have the overhead involved with the System.Drawing.Bitmap object needing to separately process the image content (so in theory the app would run faster without this). And the second advantage is that the image content is added to the PDF in whatever native compression that it was originally in. As in the case of JPEG images, using the image’s native compression as opposed to the bitmap’s compression will result in a smaller output PDF file size. None of this will have any influence on the image quality of the output PDF but it could affect the efficiency and output PDF file size.
You were both right that it was Acrobat that was causing the fuzzy display. There is a setting in preferences called resolution, instead of using the System dpi setting by default Acrobat decided to use a custom dpi setting of 110 (I have no idea why!?!?). After setting it to system (in my case 96dpi) the images were crystal clear.

Resources