Import image in Acrobat using JavaScript (preferred on document-level) - javascript

I am going to implement a dynamic legend using JavaScript in Adobe Acrobat.
The document contains a lot of layers. Every layer has an own legend. The origin idea is to implement the legend so, that it contains the images in a dialog box for the visible layers.
I can only hide/show the layers by setting state to false or true (this.getOCGs()[i].state = false;) on document-level.
Question 1: Can I extract data from layer somehow for legend establishing? I think no, as we only have these function on layers: getIntent(), setIntent() and setAction(). Right? Therefore I decided to arrange it so, that all needed icons for every layer are saved in a folder with corresponding names. JavaScript should import the icons and I build the a dialog window with icons of visible Layers and place a text(description for this icon).
I tried all possibilities of image import described here: http://pubhelper.blogspot.com.au/2012/07/astuces-toolbar-icons-et-javascript.html. I got only one way (Convert the icons as hexadecimal strings). This way isn't good, as it is too much work to create with an other tool a hexadecimal string from a images and place it into a javascript code.
Unfortunately, I cannot import image using other methods:(. Since the security settings in Adobe are changed after version 7 or so, it is not possible to use functions like app.newDoc, app.openDoc, even app.getPath On document-level. I decided to implement the import on a folder level using trusted functions like this:
Variant 1:
var importImg = app.trustedFunction(function() {
app.beginPriv();
var myDoc = app.newDoc({
nWidth: 20,
nHeight: 20
});
var img = myDoc.importIcon("icon", "/icon.png", 0);
app.endPriv();
return img; });
var oIcon = importImg();
The settings in Preferences->JavaScript-> JavaScript Security are disabled (Enable menu item JS execution privileges, enable global object security policy)
NotAllowedError: Security settings prevent access to this property or method.
App.newDoc:109:Folder-Level:User:acrobat.js
Variant 2:
var importImg = app.trustedFunction(function() {
var appPath = var phPath = app.getPath({
cCategory: "user",
cFolder: "javascript"
});
try {
app.beginPriv();
var doc = app.openDoc({
cPath: phPath + "/icon.png",
bHidden: true
});
app.endPriv();
} catch (e) {
console.println("Could not open icon file: " + e);
return;
}
var oIcon = util.iconStreamFromIcon(doc.getIcon("icon"));
return oIcon;});
var oIcon = importImg();
Could not open icon file: NotAllowedError: Security settings prevent access to this property or method.
At least it allows the execution of all these functions like app.newDoc, but in the second variant it says, wrong range of content or so. Maybe is here the pdf from an image created false? I just took the image and printed it into a pdf.
I tried all these possibilities with .jpg, .png, .pdf. with different sizes(big images and 20x20), It doesn't work.
Could somebody help me, as I spent a lot of time with trying different possibilities. It would be actually better to implement the main goal described above on document level, is it possible?
Thank you and kind regards,
Alex

Do you have the Console fully activated in Acrobat? If not, do so and look for error messages you get.
The first variant does not work, because myDoc is not defined (unless you have done that before you call the importImg function).
If you want to import the image into the newly created file, you will have to make a reference to the Document Object you create with newDoc(). Actually, that would make the link to myDoc, as in
var myDoc = app.newDoc(1,1)
(are you sure you want to create a document measuring 1x1 pt?)
The next issue with the first variant is a bug in Acrobat, which discards "floating" Icon Objects when saving the document; you'd have to attach the Icon Object to a field to keep it; this field can be hidden, or even on a hidden Template page in the document.

Related

how to jump to page of rendered pdf

Im using pdfobject along with forcePDFJS which uses pdfjs viewer.js to render pdf's.. Once they are rendered I need to be able to jump to pages without reloading the document.. The documents can be pretty large
I've seen some mentions about using PDFApplicationViewer.pdfview.currentPageNumber. but I haven't seen a good example on how to use it correclty
I've seen two example of using the PDFApplicationViewer
1. PDFApplicationViewer.pdfview.currentPageNumber = pagNum;
2. document.getElementById('mycanvas').contentWindow.PDFApplicationViewer.pdfview.currentPageNumber = pagNum;
Althought the second on make more sense Im not sure where the contentWindow object from the element comes from. Im assuming the pdfobject embeds something that I could get access too but I can't figure it out..
Also, since I couldn't really find alot on this.. Is this even possible..
For time constraint reasons I don't want to have to put together a new viewer using pdfjs.. I like what comes with the viewer.html.. I just need to jump the pages without reloading
PDFObject.embed doesn't return any reference So I looked into the pdfObject code to see how it was embedding the pdf..
for this to work there needs to be a iframe.. So when rendering with pdfobject Im using a configureation as follows:
Notice forcePDFJS=true
if(!pageNum)
pageNum=1;
var options = {
pdfOpenParams: {
view: "FitV",
page: pageNum
},
forcePDFJS: true,
PDFJS_URL: "../pdfjs/web/viewer.html"
};
Here is code that works
var pdfviewer = document.getElementById('pdfviewer');//get the viewer element
var contenttag = pdfviewer.getElementsByTagName("iframe")[0]//got this from pdfobject code
contenttag.contentWindow.PDFViewerApplication.pdfViewer.currentPageNumber = parseInt(pageNum);//change the page
In my case, the pdfviewer id is not available anymore.
PDFObject does return the reference of iframe that it creates. I was using basic HTML + JS so I had to save that reference to global window object to be able to access it from anywhere in the project.
Finally, with the reference we have, we can access the PDFViewerApplication object as below and manipulate the PDF:

set file attribute filesystemobject javascript

I have created a file as part of a script on a network drive and i am trying to make it hidden so that if the script is run again it should be able to see the file and act on the information contained within it but i am having trouble doing this. what i have so far is:
function doesRegisterExist(oFs, Date, newFolder) {
dbEcho("doesRegisterExist() triggered");
sExpectedRegisterFile = newFolder+"\\Register.txt"
if(oFs.FileExists(sExpectedRegisterFile)==false){
newFile = oFs.OpenTextFile(sExpectedRegisterFile,8,true)
newFile.close()
newReg = oFs.GetFile(sExpectedRegisterFile)
dbEcho(newReg.Attributes)
newReg.Attributes = newReg.Attributes+2
}
}
Windows Script Host does not actually produce an error here and the script runs throgh to competion. the only guides i have found online i have been attempting to translate from VBscript with limited success.
variables passed to this function are roughly declared as such
var oFs = new ActiveXObject("Scripting.FileSystemObject")
var Date = "29-12-2017"
var newFolder = "\\\\File-Server\\path\\to\\folder"
I know ActiveX is a dirty word to a lot of people and i should be shot for even thinking about using it but it really is a perfect fit for what i am trying to do.
Please help.
sExpectedRegisterFolder resolves to \\\\File-Server\\path\\to\\folder\\Register which is a folder and not a file.
I get an Error: file not found when I wrap the code into a try/catch block.
I tested the code on a text file as well, and there it works.
So you're either using the wrong method if you want to set the folder to hidden.
Or you forgot to include the path to the text if you want to change a file to hidden.
( Edit: Or if Register is the name of the file, add the filetype .txt ? )
If you change GetFile to GetFolder as described in https://msdn.microsoft.com/en-us/library/6tkce7xa(v=vs.84).aspx
the folder will get hidden correctly.

Saving without dialog window

I'm trying to write a script that will automate a bunch of stuff for Photoshop CS5. Part of this involves saving a bunch of files. Is there a way to save a file in a way that doesn't open up a dialog window? I've been looking over the JavaScript Tools Guide, but I didn't see a way to do this. This suggested I used an action to deal with it but I'd really prefer not to do that.
EDIT: specifically I want to save the files as crytiff format but I'd just like to know how to save a file with whatever extension I want
The following saves the active document as PNG. You can change the type to save it as.
// reference open doc
var doc = app.activeDocument;
// set save options
var opts = new ExportOptionsSaveForWeb();
opts.PNG8 = false;
opts.transparency = true;
opts.interlaced = false;
opts.quality = 100;
opts.includeProfile = false;
opts.format = SaveDocumentType.PNG; // Document Type
// save png file in same folder as open doc
activeDocument.exportDocument(doc.path, ExportType.SAVEFORWEB, opts);
Try using Document.saveAs(). But, like El Cas said, you still have to pass in some kind of SaveOptions object. You don't necessarily have to specify all the options if you don't want. You can just use the generic object like this:
app.activeDocument.saveAs(new File(doc.path + "/myDocument"), TiffSaveOptions);
// or BMPSaveOptions or GIFSaveOptions or JPEGSaveOptions...
Here's a much more complete Photoshop CS5 Javascript Reference
Open:
Windows > Actions
You will find Toggle Dialog On/Off check box before every action. Turn it off.

Exporting frame from external swf to Javascript

I am trying to capture a still frame from an (any) external swf file, by using my own flash movie as a proxy to load it and hand information regarding the Stage onto javascript. I want to keep it as wide compatible as possible, so I went with AS2 / Flash 8 for now.
The script works fine in the Flash debugger, i.e. the
trace(flash2canvasScreenshot.getPixel(w, h).toString(16));
returns the correct pixel color, where as:
ExternalInterface.call("sendToJS",flash2canvasScreenshot.getPixel(w, h).toString(16));
in the published movie doesn't.
This method can obviously be quite slow for large flash (dimension wise) movies, as it iterates every single pixel. If someone has any better methods in mind, feel free to share, but as said, the problem I am facing is that I am getting differentiating results in debugging and publishing, with the pixel information not getting fetched when published.
import flash.display.BitmapData;
import flash.external.*;
var myLoader:MovieClipLoader = new MovieClipLoader();
var mclListener:Object = new Object();
mclListener.onLoadInit = function(target_mc:MovieClip)
{
var stageW = Stage.width;
var flash2canvasScreenshot:BitmapData = new BitmapData(stageW, Stage.height, false, 0x00000000);
var pixels:Array = new Array();
flash2canvasScreenshot.draw(element);
for (w = 0; w <= stageW; w++)
{
trace(flash2canvasScreenshot.getPixel(w, h).toString(16)); // this gives correct color value for the pixels in the debugger
ExternalInterface.call("sendToJS",flash2canvasScreenshot.getPixel(w, h).toString(16)); // this just returns the bitmap default color, 0 in this case.
/*
for (h = 0; h <= Stage.height; h++)
{
var pixel = flash2canvasScreenshot.getPixel(w, h).toString(16);
pixels.push(pixel);
}
*/
}
//ExternalInterface.call("sendToJS",pixels.toString());*/
};
myLoader.addListener(mclListener);
myLoader.loadClip("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf", 0);
//myLoader.loadClip("https://s.ytimg.com/yt/swfbin/watch_as3-vflJjAza6.swf", 0);
//myLoader.loadClip(_level0.flash2canvasurl, _root.mc);
There are few problems with the snippet you posted:
like the one Joey mentioned, but the one that stands out from my
point of view is the element variable which isn't defined
anywhere, so that either is a type o, or you're trying to draw an
undefined object.
You're drawing as soon as the load is finished, but the animation you're loading might start slightly later. Maybe take the snapshot a bit after the load is complete.
Haven't touched as2 for some time and don't remember how security issue are handled, but if you're swf is loading another swf from a different domain, then the domain hosting the swf you're loading should also have a crossdomain.xml policy file allowing you to access the content of the loaded swf. If you simply load and display a swf from another domain, that's fine. However, if you're trying to draw the swf using BitmapData, you're actually attempting to access pixel data from the content of that swf, therefore you would need permissions. If you have no control over the crossdomain policy file, you might need to use a server side script to copy/proxy the file over to a domain that can grant your loaded swf access.
Here's a simplified version of your snippet that works (sans the external interface/pixel values part):
var myLoader:MovieClipLoader = new MovieClipLoader();
var mclListener:Object = new Object();
mclListener.onLoadInit = function(target_mc:MovieClip)
{
var pixels:Array = new Array();
setTimeout(takeSnapshot,2000,target_mc);
}
myLoader.addListener(mclListener);
myLoader.loadClip("http://www.bbc.co.uk/science/humanbody/sleep/sheep/reaction_version5.swf",1);
//myLoader.loadClip("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf", 1);
//myLoader.loadClip("https://s.ytimg.com/yt/swfbin/watch_as3-vflJjAza6.swf", 0);
function takeSnapshot(target:MovieClip):Void {
var flash2canvasScreenshot:BitmapData = new BitmapData(150, 150, false, 0x00000000);//tiny sample
flash2canvasScreenshot.draw(target);
_level1._alpha = 20;//fade the loaded content
_level0.attachBitmap(flash2canvasScreenshot,0);//show the snapshop. sorry about using _root
}
Here's a quick zoomed preview of the 150x150 snap:
Here's an as3 snippet to illustrate the security sandbox handling issue:
var swf:Loader = new Loader();
swf.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderComplete);
swf.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,loaderSecurityError);
swf.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,loaderIOError);
swf.load(new URLRequest("http://i.cdn.turner.com/cnn/cnnintl_adspaces/2.0/creatives/2010/6/9/21017300x250-03.swf"),new LoaderContext(true));
function loaderComplete(event:Event):void{
setTimeout(takeSWFSnapshot,2000);
}
function loaderSecurityError(event:SecurityErrorEvent):void {
trace('caught security error',event.errorID,event.text);
}
function loaderIOError(event:IOErrorEvent):void{
trace('caught I/O error',event.errorID,event.text,'\tattempting to load\t',swf.contentLoaderInfo.url);
}
function takeSWFSnapshot():void{
var clone:BitmapData = new BitmapData(swf.content.width,swf.content.height,false,0);
try{
clone.draw(swf.content);
}catch(e:SecurityError){
trace(e.name,e.message,e.getStackTrace());
}
addChild(new Bitmap(clone));
}
HTH
My approach to this would be:
-Use AS3 for the reason lukevanin commented:
Just remember that AS3 can load an AS2 SWF, but an AS2 SWF cannot load
an AS3 SWF, so you actually achieve greater compatibility (with your
content) if you publish AS3
-Use a proxy file to fetch the swf file to get around sandbox violation issues (although if the swf loads external resources and uses relative paths it might get a bit more complex)
-Take a snapshot of the frame ( see George Profenza's solution )
-Encode the image using base64 and send that** to a JS method, and then decode to get the image.
** I'm pretty sure there are no size limitations...

Tag images in the image itself? HOW-TO

How to tag images in the image itself in a web page?
I know Taggify, but... is there other options?
Orkut also does it to tag people faces... How is it done?
Anyone knows any public framework that is able to do it?
See a sample bellow from Taggify:
I know this isn't javascript but C# 3.0 has an API for doing this. The System.Windows.Media.Imaging namespace has a class called BitmapMetadata which can be used to read and write image metadata (which is stored in the image itself). Here is a method for retrieving the metadata for an image given a file path:
public static BitmapMetadata GetMetaData(string path)
{
using (Stream s = new System.IO.FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
var decoder = BitmapDecoder.Create(s, BitmapCreateOptions.None, BitmapCacheOption.OnDemand);
var frame = decoder.Frames.FirstOrDefault();
if (frame != null)
{
return frame.Metadata as BitmapMetadata;
}
return null;
}
}
The BitmapMetadata class has a property for tags as well as other common image metadata. To save metadata back to the image, you can use the InPlaceBitmapMetadataWriter Class.
There's a map tag in HTML that could be used in conjunction with Javascript to 'tag' different parts of an image.
You can see the details here.
I will re-activate this question and help a bit. Currently the only thing i have found about is http://www.sanisoft.com/downloads/imgnotes-0.2/example.html . A jQuery tagging implementation. If anyone knows about another way please tell us.
;)
You can check out Image.InfoCards (IIC) at http://www.imageinfocards.com . With the IIC meta-data utilities you can add meta-data in very user-friendly groups called "cards".
The supplied utilities (including a Java applet) allow you to tag GIF's, JPEG's and PNG's without changing them visually.
IIC is presently proprietary but there are plans to make it an open protocol in Q1 2009.
The difference between IIC and others like IPTC/DIG35/DublinCore/etc is that it is much more consumer-centric and doesn't require a CS degree to understand and use it...

Categories

Resources