wäre es möglich (evtl. per Script), Bildern direkt nach dem Import (außerhalb des Satzspiegels, um sie später einzubinden) eine feste Größe von sagen wir mal 80x40mm zu geben, so dass nicht nur der Bildrahmen, sondern auch das Bild an sich diese Werte annimmt? Hab das Problem, dass ich jedes platzierte Bild manuell an das Grundlinienraster anpassen muss, und da fehlen seitlich und oben bzw. unten ein paar Null-Komma-irgendwas-Millimeter. Bilder so zu skalieren ist nicht schön, aber in diesem Fall notwendig.
hab ich doch ein bisschen schnell geschossen ... Das Script skaliert jedes Element im Dokument. Wie kann ich es anpassen, dass es nur das momentan aktive skaliert?
tolles script - eine frage hätte ich jedoch dazu: wie kann man zusätzlich auch noch bestimmen, wo der verkleinerte rahmen dann seine x/y-position haben soll - derzeit nimmt er ja einfach 0/0. ich hätte jedoch lieber ca. 2cm weiter unten (vom linken rand würde der standard-abstand passen)
Martin, ich glaube, Ferdinand wollte nicht den Rahmen anders positionieren, sondern das Bild im Rahmen. Das wird dann natürlich gleich viel komplizierter.
danke - funktioniert super! gibts übrigens eine möglichkeit, dass indesign alle rahmen von allen seiten auswählen soll? mir ist gerade aufgefallen, mit "apfel"+"a" markiert er nur die rahmen des aktuellen druckbogens, aber nicht von allen 50 seiten.
Auswählen kann man tatsächlich nur Objekte des aktiven Druckbogens - auch per Skript. Aber man könnte per Skript blind (ohne Auswahl) alle Bildrahmen abarbeiten.
Ohne es geprüft zu haben, müßte das durch folgende Umdefinition der Variable mySel funktionieren:
Freilich müßten dann die Bedingungen (if-Abfragen) noch angepaßt werden. Ganz allgemein könnte man alle graphischen Rahmen folgendermaßen behandeln:
Tolles Skript, aber ich habe mal ein Frage, ich bin gerade dabei das Skript auf meine Ansprüche umzubauen, aber ich habe nicht ganz so viel Ahnung mit den Skriptbefehlen. Das erwähnte Skript skaliert die Bilder ja genau auf 8 x 4 cm. Ich bräuchte aber ein Skript, in dem nur die Bildbreite feststeht und die Höhe proportional dazu skaliert wird. Kann mir jemand weiterhelfen?
Man könnte das Bild auf Breite bringen, proportional an Rahmen anpassen und dann den Rahmen an den Inhalt anpassen. Das geht aber nur, wenn das Bild ursprünglich schmaler ist als gewünscht.
Wenn das Bild ursprünglich breiter ist als das Ziel, dann muss man erst den Inhalt proportional an den neuen Rahmen anpassen und dann den Rahmen an den Inhalt anpassen.
Das müsste etwa so gehen:
Viele Grüße Martin
(Dieser Beitrag wurde von Martin Fischer am 6. Mai 2009, 08:13 geändert)
Das Skript funzt einwandfrei... dankeschön! Auch wenn ich noch am Anfang stehe, ich habe es zumindestens noch hinbekommen mir aufbauend auf deinem Skript ein zweites zu schreiben, in dem der Inhalt an den Rahmen angepasst wird und nicht umgekehrt... jetzt habe ich zwei tolle Skripts die mir meine Arbeit sehr erleichtern. Ich muss mich da mal unbedingt tiefer in die Materie einarbeiten. Skripts scheint ja eine Menge neue Möglichkeiten zu eröffnen!
Soweit läuft es schon mal ganz gut mit den Skripts, die ich für die Skalierung der Bilder benutze. Ein Problem habe ich aber doch noch, habe auch schon mal ein bißchen gestöbert, aber nix passendes gefunden. Wenn ich im InDesign ein Bildausschnitt mache und dann das Bild via Skript vergrößere wird das Bild zwar vergrößert, aber der Inhalt wird an den Rahmen angepasst und der vorher gemachte Bildausschnitt ist futsch.
Das ist mein jetziges Skript:
Gibt es überhaupt die Möglichkeit den Bildausschnitt auch nach dem Ausführen des Skripts beizubehalten?
wenn der Bildausschnitt erhalten bleiben soll, darfst Du auf keinen Fall die Inhalt-Anpassen Funktionen verwenden. Diese sind dazu gemacht, das Bild in einer bestimmten Art und Weise an den Rahmen anzupassen, also den Ausschnitt zu verändern.
Schau Dir wg. dem Skalieren statt dessen mal die Transformationsmatrizen an. Ein passendes Beispiel von Gerald findest Du in Skript für 50%-Skalierung.
Hallo, ohne Skriptkenntnisse zu haben tue ich mich da etwas schwer das Skript umzuschreiben. Was muss man denn ändern um schmalere Bilder auf eine feste (größere) Bildbreite zu skalieren?
Du könntest auch das JavaScript BilderSkalieren benutzen.
Vielen Dank, Hans. Das ist schon mal ein gute Quelle für Skripts. Leider benötige ich ein Skript, welches mir verschieden große Bilder auf eine feste Breite skaliert und die Höhe proportional mit vergrößert.
Es handelt sich um ein in InDesign importiertes Word-Dokument mit (verketteten) Bildern, bei dem die Bilder auf Satzspiegelgröße skaliert werden sollen.
Nachstehend ein erster Versuch, die Bilder auf die Satzspiegel-Breite (oder -Höhe) zu bringen. In der Hoffnung, dass ich die Aufgabe richtig verstanden habe.
Einen Textrahmen auswählen, welcher die Textkette enthält und das Script starten.
// vorbeugenderweise das Anzeigen von Dialogen aktivieren app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
// prüfen, ob ein Dokument geöffnet ist if (app.documents.length == 0) { alert ("Es ist kein Dokument offen.", "Achtung"); exit(); }
// das Dokument im Vordergrund var curDoc = app.documents[0];
// prüfen, ob ein Textrahmen ausgewählt ist var curSel = app.selection; var nFrames = curSel.length; if (nFrames == 0) { alert ("Es ist nichts ausgewählt.", "Stop"); exit(); } else if (nFrames != 1) { alert ("Nur *einen* Textrahmen auswählen.", "Achtung"); exit(); } if (curSel[0].constructor.name != "TextFrame") { alert ("Einen Textrahmen auswählen.", "Stop"); exit(); }
// die Masseinheiten speichern, falls notwendig auf "Pixel" umstellen var vM = curDoc.viewPreferences.verticalMeasurementUnits; var hM = curDoc.viewPreferences.horizontalMeasurementUnits; if (vM != 2054187384) { curDoc.viewPreferences.verticalMeasurementUnits = 2054187384; } if (hM != 2054187384) { curDoc.viewPreferences.horizontalMeasurementUnits = 2054187384; }
// die Rectangles, welche in der Textkette verankert sind var allRects = curSel[0].parentStory.rectangles; var nRects = allRects.length;
// eine Schleife durch die Bildrahmen for (p=nRects-1; p>-1; p--) { // die Positionen der Ränder var gB = allRects[p].geometricBounds; // die Rahmenbreite var fW = gB[3]-gB[1]; if (fW < 600) { // den Vergrösserungsfaktoren ausrechnen var pC = (600/(gB[3]-gB[1])); // wenn die zukünftige Höhe kleiner als 800 px sein wird, die Breite auf 600 px bringen if (((gB[2]-gB[0])*pC) < 800) { allRects[p].geometricBounds = [gB[0], gB[1], gB[0]+((gB[2]-gB[0])*pC), gB[1]+600]; } // sonst den Rahmen auf eine Höhe von 800 px bringen else { allRects[p].geometricBounds = [gB[0], gB[1], gB[0]+800, gB[1]+((gB[3]-gB[1])*pC)]; } allRects[p].fit(FitOptions.FILL_PROPORTIONALLY); } }
// den Anwender informieren var dlog = new Window("palette"); dlog.size = [320,100]; dlog.add("statictext", [80, 100, 320, 116], "Fertig."); dlog.show(); // eine kleine Pause $.sleep(999); // das Fenster schliessen dlog.close();
zuerst einmal ein großes Dankeschön an alle Teilnehmer hier, die so tolle Arbeit leisten.
folgendes Skript funktioniert ja einwandfrei, ich möchte es nun so anpassen, dass die Variable myWidth abhängig von oneItem erzeugt wird. Ich habe hier schon mit if etc herumexperimentiert, komme aber nicht wirklich voran.
Die Idee dahinter ist folgende:
Ein Katalog mit ca 1500 Bilder soll erstellt werden, inklusive Bildunterschriften. Es gibt 4 verschiedene Bildgrößen.
Die Bilder und Bildunterschrift werden mit der Datenzusammenführung importiert, optimal wäre es natürlich gleich hier eine extra Spalte anzulegen die die variable für die Bildbreite enthält, das ist aber wohl nicht so ohne weiteres machbar, daher nun meine Frage:
Wie kann ich das schon bestehende Skript so anpassen, dass für oneItem = 1,5,9 usw myWidth auf 100 definiert wird und für 2,8,23 etc eine andere breite.
es ist durchaus möglich, in Excel eine Spalte anzulegen, welche für jedes Bild die Breite enthält. Diese Spalte auswählen, kopieren, in ein neues Fensters eines Texteditors einsetzen und speichern.
Dann das folgende, ergänzte Script starten. Per Dialog wird die Textdatei ausgewählt, diese wird eingelesen und in einen Array verwandelt.
Bei jedem Umgang wird für das aktuelle Bild das aktuelle Element des Arrays als Breite verwendet.
// die Wahl der Textdatei var myFile = File.openDialog(); if (myFile == null) { exit(); }
// die Datei einlesen var myWidths = ""; var fileIsOpen = myFile.open("r"); if (fileIsOpen) { try { myWidths = myFile.read(); myFile.close(); } catch (e) { try { myFile.close(); } catch (e) { } } } if (myWidths == "") { alert ("Die Datei ist leer.", "Stop"); exit(); }
// in einen Array verwandeln ... var myArray = myWidths.split("\n"); // ... und die Reihenfolge umkehren myArray.reverse();
var mySel = app.documents[0].rectangles; for (oneItem=0; oneItem<mySel.length; oneItem++) { if (mySel[oneItem].graphics.length != 0) { // der aktuelle Wert var myWidth = myArray[oneItem]*1; var myBounds = mySel[oneItem].geometricBounds; var myFillProp = (myBounds[3] - myBounds[1] < myWidth) ? true : false; mySel[oneItem].geometricBounds = [myBounds[0], myBounds[1], myBounds[2], myBounds[1] + myWidth]; myFillProp ? mySel[oneItem].fit(FitOptions.FILL_PROPORTIONALLY) : mySel[oneItem].fit(FitOptions.PROPORTIONALLY); mySel[oneItem].fit(FitOptions.FRAME_TO_CONTENT); } } alert("Fertig.", " ");
Theoretisch funktioniert das. Aber in einem anderen Thema wurde kürzlich davor gewarnt, sich blind auf die Reihenfolge der Objekte einer Datenzusammenführung zu verlassen: http://www.hilfdirselbst.ch/...i?post=525879#525879
Sicherer wäre, den Namen des Bildes in eine zweite Datei zu geben und dann die Breite aufgrund des Namens zu ermitteln. Doch das wäre ... komplizierter.
das oben gepostete Script wird kaum brauchbar sein. Denn das Ergebnis ist nur richtig, wenn jede Seite nur ein Bild enthält und wenn kein Rahmen breiter ist, als die neue Breite.
Also: Eine Rückwärts-Schleife durch die Seiten und das Einpassen der Bilder vereinfachen:
// die Wahl der Textdatei var myFile = File.openDialog(); if (myFile == null) { exit(); }
// die Datei einlesen var myWidths = ""; var fileIsOpen = myFile.open("r"); if (fileIsOpen) { try { myWidths = myFile.read(); myFile.close(); } catch (e) { try { myFile.close(); } catch (e) { } } } if (myWidths == "") { alert ("Die Datei ist leer.", "Stop"); exit(); }
// die verwendete Absatzmarke speichern var myReturn = ""; if (myWidths.indexOf("\r\n") != -1) { myReturn = "\r\n"; } else if (myWidths.indexOf("\r") != -1) { myReturn = "\r"; } else if (myWidths.indexOf("\n") != -1) { myReturn = "\n"; } if (myReturn == "") { alert ("Keine gültige Absatzmarke (Return, New Line) gefunden.", "Stop"); exit(); }
// in einen Array verwandeln ... var myArray = myWidths.split(myReturn); // ... und die Reihenfolge umkehren myArray.reverse();
var myPages = app.documents[0].pages; var myCtr = 0; for (p=myPages.length-1; p>-1; p--) { var mySel = myPages[p].rectangles; for (oneItem=0; oneItem<mySel.length; oneItem++) { if (mySel[oneItem].graphics.length != 0) { // der aktuelle Wert var myWidth = myArray[myCtr]*1; var myBounds = mySel[oneItem].geometricBounds; mySel[oneItem].geometricBounds = [myBounds[0], myBounds[1], myBounds[2], myBounds[1] + myWidth]; mySel[oneItem].fit(FitOptions.FILL_PROPORTIONALLY); mySel[oneItem].fit(FitOptions.FRAME_TO_CONTENT); myCtr++; } } } alert("Fertig.", " ");
Das ist schon besser. Aber ob wirklich jedem Bild der entsprechende Wert zugeordnet werden kann, bleibt fraglich.
zuerst einmal vielen, vielen Dank für Deine Hilfe. Beide Skripte funktionieren wunderbar. Man muss in der Textdatei nur höllisch aufpassen, dass man gerade beim letzten Eintrag nicht aus Versehen noch einen Return setzt. Durch den reverse() wir dann nämlich der Letzte/Erste Eintrag leer sein und das Skript spuckt einen Fehler aus.
Ich habe das Skript nun so angepasst, dass man die Breite der Bilder nun direkt aus der csv auslesen kann, welche man auch für die Datenzusammenführung benutzt. In meinem Fall stehen also in der dritten Spalte die Breitenangaben des jeweiligen Datensatzes:
var fileNameColumn = 3;//Bitte hier die Spaltennummer eintragen, in der in der CSV der neue Dateiname hinterlegt ist. var csvSeparator = ','//Bitte hier den Separator der CSV-Datei eintragen
var csvFile = File.openDialog('CSV-Datei wählen');
//csv einlesen var myArray = new Array(); csvFile.open('r'); while (!csvFile.eof) { myArray.push(csvFile.readln().split(csvSeparator)[fileNameColumn-1]); } csvFile.close(); myArray.reverse();
var myPages = app.documents[0].pages; var myCtr = 0; for (p=myPages.length-1; p>-1; p--) { var mySel = myPages[p].rectangles; for (oneItem=0; oneItem<mySel.length; oneItem++) { if (mySel[oneItem].graphics.length != 0) { // der aktuelle Wert var myWidth = myArray[myCtr]*1; var myBounds = mySel[oneItem].geometricBounds; mySel[oneItem].geometricBounds = [myBounds[0], myBounds[1], myBounds[2], myBounds[1] + myWidth]; mySel[oneItem].fit(FitOptions.FILL_PROPORTIONALLY); mySel[oneItem].fit(FitOptions.FRAME_TO_CONTENT); myCtr++; } } } alert("Fertig.", " ");
..und wenn kein Rahmen breiter ist, als die neue Breite.
-> gilt auch für die Höhe!
Die Lösung ist, den Rahmen für das Bild vor der Datenzusammenführung möglichst klein zu halten.
Das Skript funktioniert perfekt, vielen Dank nochmals!
dieses Skript läuft bei mir sehr gut. Ich möchte aber nicht den Rahmen, in dem das Bild steckt, skalieren, sondern das Bild selbst und es anschließend zusätzlich zentrieren? Wie kann ich das Bild selbst ansprechen?