Mass export all images as individual JPEGs in InDesign? - scripting

I am new to Indesign. I have a file that contains images with Photoshop clipping paths. I want to export all the clipped images in a folder. I have tried doing the "Copy Links To" and it successfully exported the original images. However, I do not want the original images but the clipped images instead. Is there a way for me to export all the clipped images as JPEG and not the original linked image? In short, I want to export the images without their background. I hope I'm making sense. I have about 800-1000 images so a batch processing method would be highly appreciated.
I found this script from one of the posts here and modified it a bit to suit my needs. It appears to work in most of my INDD documents, but it fails in others. I wonder why. I sometimes get the error message that
Error string: null is not an object
Source: fileName = File ( rect.graphics[0].itemLink.filePath ).name;
I also noticed that it skips some objects and won't download all of the images. I guess it skips those that are not in rectangles.
test();
function test()
{
var myDoc = app.activeDocument,
apis = myDoc.allPageItems, rect, fileName;
while ( rect = apis.pop() )
{
if ( !(rect instanceof Rectangle) || !rect.graphics[0].isValid ){ continue;}
fileName = File ( rect.graphics[0].itemLink.filePath ).name;
fileName = fileName.replace( /\.[a-z]{2,4}$/i, '.jpg' );
app.jpegExportPreferences.exportResolution = 2400;
app.jpegExportPreferences.jpegQuality = JPEGOptionsQuality.MAXIMUM;
//give it a unique name
var myFile = new File ("C:/Users/RANFacistol-Mata/Desktop/Image Trial/"+ fileName);
rect.exportFile(ExportFormat.JPG, myFile);
}
}
Is there a way for me to modify this script such that instead of iterating through all the rectangles, I would iterate through all of the objects instead, much like clicking this next button
And then check if that object contains an image (jpg, tiff, psd, ai, eps). If it does, then I will export it as scripted above.
Thank you for your help!

You can traverse the links present inside the document with the following snippet, this will take less time as taken by the snippet above...
You can also get the type of link ('eps' or ' pdf' etc) with linkType attribute and filePath with 'filePath' attribute of each link object..
var theDoc = app.documents.item(0);
var theLinkLen = theDoc.links.length;
for(var i = 0; i < theLinkLen; ++i)
{
var link = theDoc.links.item(i);
alert("link name \"" + link.name + "\"" + " has type \"" + link.linkType + "\""+ " with filePath \"" + link.filePath + "\"");
}

Related

ImageMagick.Net - convert pdf to tiff

I am running into an issue when converting from pdf to tiff. Here is the code I used (based on a sample provided in the documentation):
private void convImageMx(string pdfFile)
{
var settings = new MagickReadSettings();
// Settings the density to 300 dpi will create an image with a better quality
settings.Density = new Density(300, 300);
settings.ColorType = ColorType.TrueColor;
string tifpath = Path.GetDirectoryName(pdfFile) + "\\" + Path.GetFileNameWithoutExtension(pdfFile);
using (var images = new MagickImageCollection())
{
// Add all the pages of the pdf file to the collection
images.Read(pdfFile, settings);
var page = 1;
foreach (var image in images)
{
// Write page to file that contains the page number
image.Format = MagickFormat.Ptif;
image.Crop(image.Width, image.Height);
image.Write(tifpath + "_p_" + page + ".tif");
page++;
}
}
}
When I provide a multiple pdf as input, I get multiple tiff files - one file per page. However, each file contains 7 pages which are shrinking images of the original page and the size is very large (original pdf size is 328k, the size of one tiff is 67mb!).
I think I need to set the compression property as well as crop property correctly. But did not find any documentation with .NET.
[EDIT] I commented the line with density so that the size issue is fixed. However, the repeating images is still an issue.

PDFBox_Facing issue while extracting a certain image from the top of each page

Recently I had asked THIS QUESTION to be able to save all the images present in a PDF file on the File System and I was able to save the images successfully.
I tested my code on a lot of pdf files and it ran just fine. But, today I came accross THIS pdf file from where it is not able to extract some images(attached below).
Can anyone please tell me what else I can do to extract these images? Is it even possible to extract them? Are they really images or something else? I would really appreciate the help.
My code(Please ignore the hardcoding as I am still testing this out):
function fn_getAllImages()
{
var strPdf = "C:\\Users\\a614923\\Desktop\\haka\\Work\\2017\\10. October\\31\\test.PDF";
var strout = "C:\\Users\\a614923\\Desktop\\haka\\Work\\2017\\10. October\\31\\Newfolder\\img"
intPage = 2; //for the 2nd page(the image is present in the 2nd page)
var objPdf = JavaClasses.org_apache_pdfbox_pdmodel.PDDocument.load_3(strPdf);
var objPage = objPdf.getDocumentCatalog().getAllPages().get(intPage-1);
var objImages = objPage.getResources().getXObjects().values().toArray();
var objImage, objImgBuffer, objImageFile;
for(var i=0; i<objImages.length; i++)
{
objImage = objImages.items(i);
Log.Message(objImage.toString());
if(aqString.Find(objImage.toString(),"PDXObjectForm",0,false)>0)
{
continue;
}
else
{
objImage.write2file_2(strout+i);
//objImgBuffer = objImage.getRGBImage();
//objImageFile = JavaClasses.java_io.File.newInstance(strout+i+".png");
//JavaClasses.javax_imageio.ImageIO.write(objImgBuffer,"png",objImageFile);
}
}
}
The image in the PDF file which I want to save(the one inside the red box below):

Illustrator variables - dynamically line up two text strings next to each other when autogenerating

I am automating the generation of several thousand labels in Adobe Illustrator. The use of the VariableImporter script has made easy work of it so far, but now I have reached an issue where I am stumped. The original plan worked great, until the powers that be requested that one line of text have a bold text string, followed by a normal weight text string. Before, when the font weights were the same I could have connected the two strings of text in the CSV file prior to loading them into the drawing, and they would have came out lying right next to each other. This is now no longer possible and I can't think of a solution that is not incredibly fussy.
I don't know illustrator very well, so I am thinking I could just be unaware of some setting that would stick an object next to another one even as the other one moves.
Okay here is the way I figured out how to do this with help from Adobe forums and from Vasily.
First of all, use InDesign if possible. It is better at performing a Data Merge and can do this without your scripting.
Write out <variable1> <variable2> which is formatted as needed on the same line of text.
You will need to have the variables that you are putting in there somewhere in the illustration. Recommended to put it in a hidden layer behind everything.
replace variable1 and variable2 with the names of your variables where the functions getVariableContents() are called in this script
var idoc = app.activeDocument;
var vars = idoc.variables;
var replace1 = /<variable1>/g;
var replace2 = /<variable2>/g;
// author CarlosCanto on adobe forums
function getVariableContents(variableName) {
var idoc = app.activeDocument;
var ivar = idoc.variables.getByName(variableName);
return ivar.pageItems[0].contents;
}
var replaceWith1 = getVariableContents('variable1'), result;
var replaceWith2 = getVariableContents('variable2'), result;
// regex_changeContentsOfWordOrString_RemainFormatting.jsx
// regards pixxxel schubser
function exchangeWords(s, replacer) {
var s = s;
var replacer = replacer;
var atfs = activeDocument.textFrames;
for (var i = atfs.length - 1; i >= 0; i--) {
atf = atfs[i];
while (result = s.exec(atf.contents)) {
try {
aCon = atf.characters[result.index];
aCon.length = result[0].length;
aCon.contents = aCon.contents.replace(s, replacer);
} catch (e) {};
}
}
}
exchangeWords(replace1,replaceWith1);
exchangeWords(replace2,replaceWith2);
run the script
There is a way to accomplish this by having a script do some processing during the course of your batch output, and an organizational system which adds some overhead to your file, in terms of adding more text boxes and possibly an extra layer to your document. But - here's what you can have: a hidden layer with all your variables there in separate single point-text objects, and a layer with your regular template objects such as any point text or area-text objects. Your art text objects will need to be re-worked to contain a string with multiple variable placeholders like this: "Hello, <FirstName> <LastName>". The placeholders can be styled, and a processing script would then need to replace the <placeholder> words with your real variable values. Where are the varible values? They are going to be populating into your hidden layer which has your separate text objects and the script would need to read the contents of each of those to put into the <placeholders>. ~~Those same text fields can be styled as you wish, and the script could apply the same styles to your text when it is replaced in the main text body.~~ -actually this won't be necessary of your routine backs up the original text frame with the placeholder in it, therefore preserving the styling, but it may be necessary if you are going to instead use an external text file to keep your original text in. And of course, it will need to make a backup of the original text with all the <placeholders> so that it will reset the text for every new dataset during your batch process.
However, this is much easier done in Indesign, can you not use ID for your task?
I modified script from #tucker-david-grebitus's answer. So now it gets all textual variables and replaces all their names edged by percent symbol
for (var i = activeDocument.variables.length - 1; i >= 0; i -= 1) {
var variable = activeDocument.variables[i];
if (variable.kind !== VariableKind.TEXTUAL || !variable.pageItems.length) {
continue;
}
var search = new RegExp('%' + variable.name + '%', 'g');
var value = variable.pageItems[0].contents;
for (var j = activeDocument.textFrames.length - 1; j >= 0; j -= 1) {
var textFrame = activeDocument.textFrames[j];
textFrame.contents = textFrame.contents.replace(search, value);
}
}

Apps Script save as pdf doesn't include drawings and images

I want to save a Google Doc file as a pdf in the same Google Drive folder as my current file. I know I can download the file as a pdf, but then I have to upload it into the same Google Drive folder. I am trying to skip the upload step.
I have created a script to accomplish all of this, but I cannot get the images and drawings to be included in the resulting pdf.
Here is my code:
function onOpen() {
// Add a custom menu to the spreadsheet.
var ui = DocumentApp.getUi();
var menu = ui.createAddonMenu();
menu.addItem('Save As PDF','saveToPDF')
.addToUi();
}
function saveToPDF(){
var currentDocument = DocumentApp.getActiveDocument();
var parentFolder = DriveApp.getFileById(currentDocument.getId()).getParents();
var folderId = parentFolder.next().getId();
var currentFolder = DriveApp.getFolderById(folderId);
var pdf = currentDocument.getAs('application/PDF');
pdf.setName(currentDocument.getName() + ".pdf");
// Check if the file already exists and add a datecode if it does
var hasFile = DriveApp.getFilesByName(pdf.getName());
if(hasFile.hasNext()){
var d = new Date();
var dateCode = d.getYear()+ "" + ("0" + (d.getMonth() + 1)).slice(-2) + "" + ("0" + (d.getDate())).slice(-2);
pdf.setName(currentDocument.getName() + "_" + dateCode +".pdf");
}
// Create the file (puts it in the root folder)
var file = DriveApp.createFile(pdf);
// Add to source document original folder
currentFolder.addFile(file);
// Remove the new file from the root folder
DriveApp.getRootFolder().removeFile(file);
}
Is there another way to create the pdf, save to the current Google Drive folder, and not lose the images?
UPDATE
I just tested and realized that even if I export as a pdf, the images and drawings aren't included. There has to be a way to do this.
UPDATE 2
I have been testing some more and have learned a few things:
Images in the header/footer are included if they are In line, but if I use Wrap text or Break text they are not.
Images in the body can be any of the three
However, if I use the "Project Proposal" template, they include an image in the footer with Break text and it exports to pdf. I can't tell why their image is any different.
I don't want to use In line because I want the image to touch both sides of the page and In line will always leave at least 1 pixel to the left of the image.

How to Download PDF Links in Column and Save to Common Folder

We have a column that contains links to PDFs that starts on line 4 (e.g B4:B). I am trying to find a way to automatically download the PDF files that are accessed via the links to a folder on Drive. This is what I have so far:
function savePDFs() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 3; i < data.length; i++) {
Logger.log(data[i][1]);
}
}
Presumably the above code would write the links starting in column B (index value of [1]) on row 4 (i value of 3) (ie., B4) until the bottom of the data set (eg., data.length()).
I'm now confused about how to access and save the PDF link that are written in the logger to a folder.
Would someone be willing to help me out? I'm currently having to go to each link, click Save Link As... and then navigate to the folder that I'd like to save the linked PDF to. My hope is to modify the above process using code.
Update: I found this bit of code here that may help me out. Note, I changed the PDF link to a currently valid PDF link.
var urlOfThePdf = 'http://download.p4c.philips.com/l4b/9/929000277411_eu/929000277411_eu_pss_aenaa.pdf';// an example of online pdf file
var folderName = 'GAS';// an example of folder name
function saveInDriveFolder(){
var folder = DocsList.getFolder(folderName);// get the folder
var file = UrlFetchApp.fetch(urlOfThePdf); // get the file content as blob
folder.createFile(file);//create the file directly in the folder
}
Okay, I'm going to go and noodle with the data that is in the logger to confirm that the data is in properly formatted PDF links, then I'm going to test this new bit of code out. I feel like I'm getting close.
You can't force a download of a file from an apps script, you must try that from an HTMLService and not sure it will work.
For your need I would recommend to create a dedicated folder and you add all the pdf in it and you use the download function of the drive interface to download all files in one clic.
In drive, a file can be put in several folders so the pdf files stay in the original folder but you create a new folder 'PDF for download" for example and you put them in it. To do that from drive interface you have to click on "shift"+Z when file(s) is/are selected.
For you current list of file you just have to add in your loop the add to folder function. You can use this function.
function addFileToFolder(id){
var folderPDF = DriveApp.getFolderById("Id OFFolder to put pdf");
var file = DriveApp.getFileById(id);
folderPDF.addFile(file);
}
EDIT : Function will browse list of url, get the file and make a copy in a dedicated folder on the user drive.
function downloadInDriveFolder(){
var folderID = 'Id of the folder';// put id of the folder
var folder = DriveApp.getFolderById(folderID)// get the folder
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 3; i < data.length; i++) {
var blob = UrlFetchApp.fetch(data[i][1]).getContent();
var pdf = DriveApp.createFile(blob);
pdf.setName(data[i][0]);//Put as name of the file the value in col A
folder.addFile(pdf);
}
}
Well I figured it out. I was expecting more code, but this does it for me:
function listPDFs() {
var out = new Array();
var row = 3; //row index of 0 = row 1
var column = 4; // column index of 0 = column A
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var folder = DriveApp.getFolderById("this is where you paste your folder id"); // destination folder (this is the 0978SDFSDFKJHSDF078Y98hkyo looking value when you right click your folder and select "Get Link")
for (var i=row ; i<data.length ; i++) {
if(data[i][column] !== "") {
var file = UrlFetchApp.fetch(data[i][column]);
folder.createFile(file);
}
}
return
}
As you can see, I included a row and column variable so that I could easily change these.
I haven't figured out how to assemble them into a merged PDF, but I did figure out that I could sort them by date (which places the top most item first) and then right click and select "Open With...PDF Mergy", which then moves the PDFs into PDF Mergy and merges them up in the correct order. You can find PDF Mergy in the Chrome App Store. If I figure out how to automatically call PDF Mergy from GAS, I'll post that up--but for the time being the above code has saved us a ton of time...so I'm calling it good enough for the time being.