Neuer Versuch: <
bildgröße_jpgtif.vbs>, Version 0.3
Version 0.3 des Scripts unterstützt *.jpg-
und *.tif-Dateien.
Die Fehler des alten Scripts bei der Ermittlung des DIN-Papierformats (und dessen Größe) habe ich hoffentlich beseitigen können.
Was die Anzeige der Bildausgabegröße und der Papierfläche betrifft, habe ich jetzt die Darstellung
{B} cm × {H} cm gewählt. Ich jedenfalls halte diese Form für Flächenangaben nicht für falsch. Man kann dies im Script ja je nach Gusto ändern, ein paar auskommentierte Alternativdarstellungen sind schon enthalten.
Neu habe ich eine "Druckerempfehlung" aufgenommen, die entsprechend der Bildausgabegröße einen Drucker / Plotter aus dem Wertebereich "A4-Drucker", "A3-Drucker", "Plotter 30 cm", ..., "Plotter 105 cm", "(Kein Drucker)" auswählt.
Entsprechend gibt es ein Flag zum Ein-/Ausblenden dieser Info und eine Flag, welches steuert, ob die Druckränder auf das ermittelte DIN-Papierformat oder auf das vom empfohlenen Drucker maximal verarbeitbare Papierformat bezogen werden sollen.
Der Ausgabestring für die Druckränder enthält jetzt zusätzlich die Angabe, ob das Bild für die Ausgabe auf dem Drucker gedreht werden muss ("90°") oder nicht ("0°").
Hier nun das Script (ist leider ziemlich monströs geworden). Für weitere Fehlerhinweise wäre ich dankbar:
Code: Select all
'*** Bildgröße_jpgtif.vbs, V0.3, 18.03.2006, van Dusen
'*** Script for Script Content Plugin
'*** (c)Lev Freidin, 2005
'*** http://www.totalcmd.net/plugring/script_wdx.html
'*** http://wincmd.ru/plugring/script_wdx.html
Dim fso, f
Set fso = CreateObject("Scripting.FileSystemObject")
result = ""
'*** Welche Angaben soll der Ergebnis-String enthalten?
'*** 0 = Nicht anzeigen
'*** 1 = Anzeigen
booZeigeAufloesungsKategorie = 1
booZeigeBildAufloesungDPI = 1
booZeigeBildGroessePixel = 1
booZeigeBildAusgabeGroesseCm = 1
booZeigeDrucker = 1
booZeigePapierMassDIN = 1
booZeigePapierGroesseCm = 1
'*** 0 = Nicht anzeigen
'*** 1 = Ränder auf das ermittelte DIN-Format beziehen
'*** 2 = Ränder auf das vom empfohlenen Drucker max. verarbeitbare Papierformat beziehen
booZeigePapierRaenderMm = 2
'*** 0 = DIN A-, B-, C- und D-Formate verwenden
'*** 1 = Nur Papiermaße der DIN A-Serie verwenden
booZeigePapierMassDINnurA = 1
'====================================================================================================
'JPEG-Dateien auswerten
'====================================================================================================
If LCase(fso.GetExtensionName(filename)) = "jpg" Then
'*** xFFD8: Start Of Image-Tag
segsoi = Chr(255) & Chr(216)
'*** xFFE0: JFIF-Tag
segjff = Chr(255) & Chr(224)
'*** xFFC0: Image Format Information-Tag
segifi = Chr(255) & Chr(192)
'*** JFIF-Tag mit der dpi/ppi-Info braucht nicht vorhanden zu sein;
'*** Fehlwert auf 72 dpi/ppi setzen, um Division durch 0 bei Berechnung der Ausgabegröße zu verhindern
ypicdpi = 72
xpicdpi = 72
picdpidef = " (Fehlwert)"
Set f = fso.OpenTextFile(filename, 1, False)
segmark = f.Read(2)
If segmark = segsoi Then
Do
segmark = f.Read(2)
seglen = Asc(f.Read(1)) * 256 + Asc(f.Read(1))
Select Case segmark
'*** JFIF-Tag
Case segjff
f.Skip(8)
ypicdpi = Asc(f.Read(1)) * 256 + Asc(f.Read(1))
xpicdpi = Asc(f.Read(1)) * 256 + Asc(f.Read(1))
'*** Wenn das JPG keine (sinnvolle) DPI-Info enthält, 72 DPI annehmen
If xpicdpi < 2 Or ypicdpi < 2 Then
xpicdpi = 72
ypicdpi = 72
Else
picdpidef = ""
End If
f.Skip(seglen - 14)
'*** Image Format Information-Tag
Case segifi
f.Skip(1)
ypicpix = Asc(f.Read(1)) * 256 + Asc(f.Read(1))
xpicpix = Asc(f.Read(1)) * 256 + Asc(f.Read(1))
Exit Do
'*** Sonstiges Tag / Lesefehler (Synchronisationsproblem)
Case Else
'*** Wenn Tag = xFF##, dann ist noch alles OK -> Tag überlesen
If Left(segmark, 1) = Chr(255) Then
f.Skip(seglen-2)
'*** Wenn Tag <> xFF##, dann ist das Script "aus dem Tritt" geraten -> Script verlassen
Else
result = "# Fehler beim Lesen der Datei"
Exit Do
End If
End Select
Loop
End If
f.Close
Set f=nothing
End If
'====================================================================================================
'TIFF-Dateien auswerten
'====================================================================================================
If LCase(fso.GetExtensionName(filename)) = "tif" Then
picdpidef = " (Fehlwert)"
lngIFDEntryValOffsetXRes = 0
lngIFDEntryValOffsetYRes = 0
unitperinch = 1
xpicpix = 0
ypicpix = 0
Set f = fso.OpenTextFile(filename, 1, False)
lngFP = 0
'*** Byteorder ("II" = little-endian; "MM" = big-endian)
booByteOrder = 0
If f.Read(2) = "II" Then booByteOrder = 1
lngFP = lngFP + 2
'*** "42"
f.Skip(2)
lngFP = lngFP + 2
'*** Offset des ersten IFD (Image File Directory) ermitteln
strRaw = f.Read(4)
lngFP = lngFP + 4
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
lngIFDOffset = 0
For i = 1 To 4
lngIFDOffset = lngIFDOffset + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
'*** Zum ersten IFD springen (8 Bytes wurden bereits gelesen)
'*** (Offsetangaben sind immer vom Start des TIF gerechnet; erstes Byte der Datei hat Offset=0)
f.Skip(lngIFDOffset - 8)
lngFP = lngFP + lngIFDOffset - 8
'*** Anzahl der Einträge des ersten IFD ermitteln
strRaw = f.Read(2)
lngFP = lngFP + 2
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
intIFDEntryCount = 0
For i = 1 To 2
intIFDEntryCount = intIFDEntryCount + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
'*** IFD-Einträge lesen: Jeder Eintrag ist 12 Bytes lang
'*** Tag(2), Datentyp(2), ValAnz(4), ValOff(4)
For intIFDEntryCurrent = 1 To intIFDEntryCount
'*** Tag
'*** Hier nur die für dieses Script interessanten:
'*** TagName Dec Hex Typ und Werte
'*** ImageWidth 256 100 SHORT oder LONG
'*** ImageLength 257 101 SHORT oder LONG
'*** XResolution 282 11A RATIONAL
'*** YResolution 283 11B RATIONAL
'*** ResolutionUnit 296 128 SHORT (1=Keine, 2=Inch (Fehlwert), 3=Zentimeter)
strRaw = f.Read(2)
lngFP = lngFP + 2
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
intIFDEntryTag = 0
For i = 1 To 2
intIFDEntryTag = intIFDEntryTag + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
'*** Datentyp des Feldes
'*** 1 = BYTE 8-bit unsigned integer
'*** 2 = ASCII 8-bit byte that contains a 7-bit ASCII code; the last byte must be NUL (binary zero)
'*** 3 = SHORT 16-bit (2-byte) unsigned integer
'*** 4 = LONG 32-bit (4-byte) unsigned integer
'*** 5 = RATIONAL Two LONGs: the first represents the numerator of a fraction; the second, the denominator
'*** 6 = SBYTE An 8-bit signed (twos-complement) integer
'*** 7 = UNDEFINED An 8-bit byte that may contain anything, depending on the definition of the field
'*** 8 = SSHORT A 16-bit (2-byte) signed (twos-complement) integer
'*** 9 = SLONG A 32-bit (4-byte) signed (twos-complement) integer
'*** 10 = SRATIONAL Two SLONG’s: the first represents the numerator of a fraction, the second the denominator
'*** 11 = FLOAT Single precision (4-byte) IEEE format
'*** 12 = DOUBLE Double precision (8-byte) IEEE format
strRaw = f.Read(2)
lngFP = lngFP + 2
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
'intIFDEntryDatatype = Hex(Asc(Left(strRaw, 1)))
'intIFDEntryDatatype = InStr("123456789ABC", intIFDEntryDatatype)
intIFDEntryDatatypeLen = CInt(Mid("112481124848", Asc(Left(strRaw, 1)), 1))
'*** Anzahl Daten
strRaw = f.Read(4)
lngFP = lngFP + 4
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
lngIFDEntryValCount = 0
For i = 1 To 4
lngIFDEntryValCount = lngIFDEntryValCount + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
'*** Offset der Daten ODER die Daten selbst
'*** (sofern die Daten in die 4 Bytes hineinpassen UND das Tag es "erlaubt")
strRaw = f.Read(4)
lngFP = lngFP + 4
If intIFDEntryDatatypeLen =< 4 Then
strRaw = Left(strRaw, intIFDEntryDatatypeLen)
iend = intIFDEntryDatatypeLen
Else
iend = 4
End If
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
lngIFDEntryValOffset = 0
For i = 1 To iend
lngIFDEntryValOffset = lngIFDEntryValOffset + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
Select Case intIFDEntryTag
Case 256
xpicpix = lngIFDEntryValOffset
Case 257
ypicpix = lngIFDEntryValOffset
Case 282
lngIFDEntryValOffsetXRes = lngIFDEntryValOffset
Case 283
lngIFDEntryValOffsetYRes = lngIFDEntryValOffset
Case 296
unitperinch = 1
If lngIFDEntryValOffset = 3 Then unitperinch = 2.54
Case Else
'NOP
End Select
Next
'*** X-Auflösung ermitteln
'*** TIFF-IFD-Tag mit der dpi/ppi-Info braucht nicht vorhanden zu sein;
'*** Fehlwert auf 72 dpi/ppi setzen, um Division durch 0 bei Berechnung der Ausgabegröße zu verhindern
xpicdpi = 72
If lngIFDEntryValOffsetXRes > 0 Then
If lngIFDEntryValOffsetXRes >= lngFP Then
f.Skip(lngIFDEntryValOffsetXRes - lngFP)
Else
f.Close
Set f=nothing
Set f = fso.OpenTextFile(filename, 1, False)
f.Skip(lngIFDEntryValOffsetXRes)
End If
lngFP = lngIFDEntryValOffsetXRes
'*** Zähler
strRaw = f.Read(4)
lngFP = lngFP + 4
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
lngZaehler = 0
For i = 1 To 4
lngZaehler = lngZaehler + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
'*** Nenner
strRaw = f.Read(4)
lngFP = lngFP + 4
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
lngNenner = 0
For i = 1 To 4
lngNenner = lngNenner + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
xpicdpi = lngZaehler * unitperinch / lngNenner
'*** Wenn das TIF keine (sinnvolle) DPI-Info enthält, 72 DPI annehmen
If xpicdpi = 0 Then
xpicdpi = 72
Else
picdpidef = ""
End If
End If
'*** Y-Auflösung ermitteln
'*** TIFF-IFD-Tag mit der dpi/ppi-Info braucht nicht vorhanden zu sein;
'*** Fehlwert auf 72 dpi/ppi setzen, um Division durch 0 bei Berechnung der Ausgabegröße zu verhindern
ypicdpi = 72
If lngIFDEntryValOffsetYRes > 0 Then
If lngIFDEntryValOffsetYRes >= lngFP Then
f.Skip(lngIFDEntryValOffsetYRes - lngFP)
Else
f.Close
Set f=nothing
Set f = fso.OpenTextFile(filename, 1, False)
f.Skip(lngIFDEntryValOffsetYRes)
End If
'lngFP = lngIFDEntryValOffsetYRes
'*** Zähler
strRaw = f.Read(4)
'lngFP = lngFP + 4
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
lngZaehler = 0
For i = 1 To 4
lngZaehler = lngZaehler + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
'*** Nenner
strRaw = f.Read(4)
'lngFP = lngFP + 4
If booByteOrder = 0 Then strRaw = StrReverse(strRaw)
lngNenner = 0
For i = 1 To 4
lngNenner = lngNenner + Asc(Mid(strRaw, i, 1)) * 256^(i-1)
Next
ypicdpi = lngZaehler * unitperinch / lngNenner
'*** Wenn das TIF keine (sinnvolle) DPI-Info enthält, 72 DPI annehmen
If ypicdpi = 0 Then
ypicdpi = 72
Else
picdpidef = ""
End If
End If
f.Close
Set f=nothing
End If
'====================================================================================================
'Ergebnisstring basteln
'====================================================================================================
If (LCase(fso.GetExtensionName(filename)) = "jpg" Or LCase(fso.GetExtensionName(filename)) = "tif") And Left(result, 1) <> "#" Then
k = 2^0.125
'*** Auflösungs-Kategorie
If booZeigeAufloesungsKategorie = 1 Then
picdpicat = "D - Screen"
If xpicdpi > 96 Or ypicdpi > 96 Then picdpicat = "C - Print (LoRes)"
If xpicdpi >= 600 Or ypicdpi >= 600 Then picdpicat = "B - Print (MedRes)"
If xpicdpi >= 1200 Or ypicdpi >= 1200 Then picdpicat = "A - Print (HiRes)"
result = result & picdpicat
End If
'*** Auflösung
If booZeigeBildAufloesungDPI = 1 Then
result = result & " • "
'*** Formal definitiv inkorrekte, aber übersichtlichere Darstellung:
If xpicdpi <> ypicdpi Then result = result & xpicdpi & " × "
result = result & ypicdpi & " ppi" & picdpidef
End If
'*** Pixelmaße
If booZeigeBildGroessePixel = 1 Then
result = result & " • " & FormatNumber(xpicpix, 0) & " × " & FormatNumber(ypicpix, 0) & " px"
End If
'*** Ausgabegröße
xpiccm = xpicpix * 2.54 / xpicdpi
ypiccm = ypicpix * 2.54 / ypicdpi
If booZeigeBildAusgabeGroesseCm = 1 Then
'*** Formal eher inkorrekte, aber übersichtlichere Darstellung:
'result = result & " • " & FormatNumber(xpiccm, 1) & "×" & FormatNumber(ypiccm, 1) & " cm²"
'*** Formal vermutlich korrekte(re) Darstellung (Variante 1: Unverknüpfte Kantenmaße):
'result = result & " • " & "B " & FormatNumber(xpiccm, 1) & "cm H " & FormatNumber(ypiccm, 1) & "cm"
'*** Formal vermutlich korrekte(re) Darstellung (Variante 2: Kantenmaße der BildFLÄCHE):
result = result & " • " & FormatNumber(xpiccm, 1) & " cm × " & FormatNumber(ypiccm, 1) & " cm"
End If
'*** Erforderliches DIN-Papiermaß (DIN Bx > DIN Cx > DIN Ax > DIN Dx)
'*** GGf. ins Hochformat "drehen" (oben/unten = kurze Kante, links/rechts = lange Kante)
xdinausricht = ""
If xpiccm > ypiccm Then
tpiccm = xpiccm
xpiccm = ypiccm
ypiccm = tpiccm
xdinausricht = " (quer)"
End If
'*** xpiccm xpiccm
'*** +----+ +--+
'*** |^ |ypiccm ---> | |ypiccm
'*** +----+ |< |
'*** +--+
'*** Paramter für das Papierformat ermitteln, und zwar getrennt für die kurze und die lange Kante des Bildes
xdinexpb = Round(Log(xpiccm/100) / Log(k), 0)
xdinexph = xdinexpb + 4
ydinexpb = Round(Log(ypiccm/100) / Log(k), 0)
'*** xdinexpb (ydinexph)
'*** +--+.+ +--+......+
'*** | | : | | :
'*** |< | :xdinexph |< | :ydinexpb
'*** +--+ : +--+ :
'*** : : +.........+
'*** +....+
'*** Das kleinstpassende der beiden oben ermittelten Papierformate wählen
If xdinexph < ydinexpb Then
xdinexpb = xdinexpb - (xdinexph - ydinexpb)
xdinexph = xdinexpb + 4
End If
'*** Durch Rundungsfehler können die Parameter für ein Paperformat gewählt worden sein, welches um einige mm zu klein ist
'*** Daher hier prüfen, ob das Bild aufs Papier passen würde und die Parameter fürs Papierformat ggf. korrigieren
'*** Toleranz: 1 mm
xdincm = k^xdinexpb * 100
ydincm = k^xdinexph * 100
If Round(xpiccm, 1) - Round(xdincm, 1) > 0 Or Round(ypiccm, 1) - Round(ydincm, 1) > 0 Then
xdinexpb = xdinexpb + 1
xdinexph = xdinexph + 1
End If
'*** Druckerempfehlung (A4- oder A3-Drucker oder Plotter + benötigte Papierrollenbreite)
drucker = "?"
'Breite Höhe
'> 0,0 > 42,0 30 cm Rolle
'> 29,7 > 59,4 42 cm Rolle
'> 42,0 > 84,1 60 cm Rolle
'> 59,4 egal 84 cm Rolle
'> 81,4 egal 105 cm Rolle (Spezialplotter)
'*** A4-Drucker (Fehlwert)
'drucker = "A4-Drucker (21,0×29,7)"
drucker = "A4-Drucker"
xpapiercm = 21.0
ypapiercm = 29.7
'*** A3-Drucker
If xdinexpb > -18 Then
'drucker = "A3-Drucker (29,7×42,0)"
drucker = "A3-Drucker"
xpapiercm = 29.7
ypapiercm = 42.0
End If
'*** Plotter
If xdinexpb > -14 Then
xpapiercm = 30
ypapiercm = 0
If xpiccm > 30 Then xpapiercm = 42
If xpiccm > 42 Then xpapiercm = 60
If xpiccm > 60 Then xpapiercm = 84
If xpiccm > 84 Then xpapiercm = 105
drucker = "Plotter " & xpapiercm & " cm"
If xpiccm > 105 Then
drucker = "(Kein Drucker)"
xpapiercm = 0
End If
End If
If booZeigeDrucker = 1 Then result = result & " • " & drucker
'*** DIN-Serie (A, B, C, D) und DIN-SerienNr bestimmen
dinserie = Mid("BDAC", (xdinexpb + 400) Mod 4 + 1, 1)
dinnr = Fix((xdinexpb + 400) / 4 - 0.25) - 99
dinnr = -1 * dinnr
'*** Wenn nur Papierformate der DIN A-Serie verwendet werden sollen,
'*** dann bei B-, C-, D-Formaten das nächstgrößere A-Papierformat bestimmen
If booZeigePapierMassDINnurA = 1 Then
xdinexpb = xdinexpb + InStr("ADBC", dinserie) - 1
xdinexph = xdinexph + InStr("ADBC", dinserie) - 1
If dinserie = "B" Or dinserie = "C" Then dinnr = dinnr - 1
dinserie = "A"
End If
If booZeigePapierMassDIN = 1 Then
'*** Übergrößen nicht mit negativen SerienNr ausgeben, sondern mit Flächenfaktor bezogen auf SerienNr 0
'*** (also z.B. "DIN 2A0" statt "DIN A-1")
If dinnr < 0 Then
result = result & " • " & "DIN " & 2^Abs(dinnr) & dinserie & "0" & xdinausricht
Else
result = result & " • " & "DIN " & dinserie & dinnr & xdinausricht
End If
End If
'*** Papiergröße, erforderliche Bilddrehung sowie Druckränder links und rechts / oben und unten ermitteln
xdincm = k^xdinexpb * 100
ydincm = k^xdinexph * 100
bilddrehung = "0°"
'*** Einstellung booZeigePapierRaenderMm = 1: Ränder auf das ermittelte DIN-Format beziehen
If booZeigePapierRaenderMm = 1 Then
xpapiercm = xdincm
ypapiercm = ydincm
If xdinausricht = " (quer)" Then bilddrehung = "90°"
End If
'*** Einstellung booZeigePapierRaenderMm = 2: Ränder auf die Druckerempfehlung beziehen
'*** (xpapiercm/ypapiercm wurden bereits oben unter "Druckerempfehlung" ermittelt)
If booZeigePapierRaenderMm = 2 Then
If xdinausricht = " (quer)" Then
If ypiccm > xpapiercm Then
bilddrehung = "90°"
Else
tpiccm = xpiccm
xpiccm = ypiccm
ypiccm = tpiccm
End If
End If
End If
xdincmresult = FormatNumber(xdincm, 1) & " cm"
ydincmresult = FormatNumber(ydincm, 1) & " cm"
If xpapiercm = 0 Then
bilddrehung = "—"
xrandresult = "—"
Else
'*** Ränder in cm
'xrandresult = FormatNumber((xpapiercm-xpiccm) / 2, 1) & " cm"
'*** Ränder in mm
xrandresult = FormatNumber((xpapiercm-xpiccm) * 5, 0) & " mm"
End If
If ypapiercm = 0 Then
yrandresult = "—"
Else
'*** Ränder in cm
'yrandresult = FormatNumber((ypapiercm-ypiccm) / 2, 1) & " cm"
'*** Ränder in mm
yrandresult = FormatNumber((ypapiercm-ypiccm) * 5, 0) & " mm"
End If
'*** Papiergröße in Ergebnisstring aufnehmen
If booZeigePapierGroesseCm = 1 Then
If xdinausricht = " (quer)" Then
'*** Darstellung: Kantenmaße der PapierFLÄCHE:
result = result & " · " & ydincmresult & " × " & xdincmresult
Else
'*** Darstellung: Kantenmaße der PapierFLÄCHE:
result = result & " · " & xdincmresult & " × " & ydincmresult
End If
End If
'*** Ränder links und rechts / oben und unten in Ergebnisstring aufnehmen
If booZeigePapierRaenderMm > 0 Then
result = result & " • " & bilddrehung & " · "
If booZeigePapierRaenderMm = 2 Or (booZeigePapierRaenderMm < 2 And xdinausricht = "") Then
result = result & xrandresult & " · " & yrandresult
Else
result = result & yrandresult & " · " & xrandresult
End If
End If
End If
content = result
Set fso=nothing