Paperclip/ImageMagick problems on Windows - ruby-on-rails-3

I managed to implement a rounded-corners post-process on my avatars. It works fine on my Mac, but no dice on Windows.
it looks like so
def self.convert_options(px = 10)
trans = ""
trans << " \\( +clone -alpha extract "
trans << "-draw 'fill black polygon 0,0 0,#{px} #{px},0 fill white circle #{px},#{px} #{px},0' "
trans << "\\( +clone -flip \\) -compose Multiply -composite "
trans << "\\( +clone -flop \\) -compose Multiply -composite "
trans << "\\) -alpha off -compose CopyOpacity -composite "
end
based on http://www.imagemagick.org/Usage/thumbnails/#rounded & Rounded corners with Paperclip
The big list of errors I got kicked off with
convert.exe: unable to open image `\\(': No such file or directory # error/blob.c/OpenBlob/2638.
I figure maybe it is something to do with Windows escaping characters? So changed the \ to ^ but got this error instead
convert.exe: unable to open image `black': No such file or directory # error/blob.c/OpenBlob/2638.
ImageMagick is working, otherwise. It manages simpler processing/resizing fine. And the line produces rounded corner files with no problem if I use GIT BASH to type out the command straight into the shell.

A good night's sleep (after hours of trying thousands of combinations) led me to this
def self.convert_options_win(px = 10)
trans = " "
trans << " ( +clone -alpha extract -draw \"fill black polygon 0,0 0,#{px} #{px},0 fill white circle #{px},#{px} #{px},0 \" "
trans << " ( +clone -flip ) -compose Multiply -composite "
trans << " ( +clone -flop ) -compose Multiply -composite ) "
trans << " -alpha off -compose CopyOpacity -composite "
end
which works fine. No real need for the continuation characters at the start of the line, as it was all being truncated into a single line string. Windows shell prefers "double quotes" to 'single quotes' so just had to escape those within the string. I tried so many combinations, can't believe it was this simple.

Related

Move margintext in line with rest of text

I was wondering how to bring the names of the places of work on the left side in one line with the job titles and the date. E.g. Praktikum Psychologie should be in line with Sonnhalde Grüningen. See compilable code below. I've tried vspace etc. but haven't had much luck. Same issue with Ausbildung (Education) as well.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Classicthesis-Styled CV
% LaTeX Template
% Version 1.0 (22/2/13)
%
% This template has been downloaded from:
% http://www.LaTeXTemplates.com
%
% Original author:
% Alessandro Plasmati
%
% License:
% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%----------------------------------------------------------------------------------------
% PACKAGES AND OTHER DOCUMENT CONFIGURATIONS
%----------------------------------------------------------------------------------------
\documentclass{scrartcl}
\reversemarginpar % Move the margin to the left of the page
\newcommand{\MarginText}[1]{\marginpar{\raggedleft\itshape\small#1}} % New command defining the margin text style
\usepackage[nochapters]{classicthesis} % Use the classicthesis style for the style of the document
\usepackage[LabelsAligned]{currvita} % Use the currvita style for the layout of the document
\usepackage[ngerman]{babel}
\renewcommand{\cvheadingfont}{\LARGE\color{Purple}} % Font color of your name at the top
\usepackage{hyperref} % Required for adding links and customizing them
\hypersetup{colorlinks, breaklinks, urlcolor=Purple, linkcolor=Purple} % Set link colors
\usepackage{enumitem}% Use the enumitem package for lists - http://ctan.org/pkg/enumitem
\setlist{nolistsep}
\newlength{\datebox}\settowidth{\datebox}{Spring 2011} % Set the width of the date box in each block
\newcommand{\NewEntry}[3]{\noindent\hangindent=1em\hangafter=0 \parbox{\datebox}{#1}\hspace{0.1em} #2 #3 % Define a command for each new block - change spacing and font sizes here: #1 is the left margin, #2 is the italic date field and #3 is the position/employer/location field
\vspace{0.5em}} % Add some white space after each new entry
\newcommand{\Description}[1]{\noindent\hangindent=2em\hangafter=0\noindent\footnotesize{#1}\par\normalsize\vspace{1em}} % Define a command for descriptions of each entry - change spacing and font sizes here
\usepackage{adforn}
%----------------------------------------------------------------------------------------
\begin{document}
\thispagestyle{empty} % Stop the page count at the bottom of the first page
%----------------------------------------------------------------------------------------
% NAME AND CONTACT INFORMATION SECTION
%----------------------------------------------------------------------------------------
\begin{cv}{\spacedallcaps{censored}}\vspace{1.5em} % Your name
\spacedlowsmallcaps{Persönliche Daten}\vspace{0.5em} % Personal information heading
\datebox=1in
\NewEntry{\large{*}}{censored}{} % Birthplace and date
\datebox=1in
\NewEntry{e-mail}{\href{mailto:censored}{censored} % Email address
\datebox=1in
\NewEntry{telefon}{censored} % Phone number(s)
\datebox=1in
\NewEntry{adresse}{censored} % Address
\vspace{1em} % Extra white space between the personal information section and goal
%\noindent\spacedlowsmallcaps{Goal}\vspace{1em} % Goal heading, could be used for a quotation or short profile instead
%\Description{Improve my skills in creating and developing cutting edge projects. Find a way to apply scientific approaches in solving practical problems. }\vspace{2em} % Goal text
%----------------------------------------------------------------------------------------
% Experience
%----------------------------------------------------------------------------------------
\spacedlowsmallcaps{Berufserfahrung}\vspace{1em}
\datebox=3.2in
\datebox=3.2in
\NewEntry{Praktikum Psychologie}{\textit{08.2022 -- 02.2023}}
\Description{\MarginText{\textsc{\href{https://www.klinik-sonnhalde.ch/}{Sonnhalde}} \\ Grüningen.} \vspace{-2mm}
\begin{itemize}
\item Pensum 40-60 \%
\item Psychotherapiegespräche im Einzelsetting
\item Co-Leitung Sozialkompetenztraining
\item Leitung Gruppe Achtsamkeit
\item Begleitung Psychiater auf Visiten
\item regelmässige Teilhabe an Supervisionen
\end{itemize}}
\datebox=3.2in
\NewEntry{Praxisassistentin}{\textit{06.2019 -- 06.2022}}
\Description{\MarginText{\textsc{Zentrum für Chiropraktik} \\ Zürich.} \vspace{-2mm}
}
\vspace{2.25em} % Extra space between major sections
\datebox=3.2in
\NewEntry{Praktikum Psychologie}{\textit{10.2020 -- 01.2021}}
\Description{\MarginText{\textsc{\href{https://www.forio.ch/}{forio AG}} \\ Frauenfeld.} \vspace{-4mm}
\begin{itemize}
\item Mitarbeit Begutachtungen und Testberichte
\item selbstständige Durchführung psychodiagnostischer Testverfahren \\(\textsc{WISC-V}, \textsc{WAIS-IV}) mit Jugendlichen und Erwachsenen
\end{itemize}}
\datebox=3.2in
\NewEntry{Mitarbeiterin Hotellerie}{\textit{09.2016 -- 09.2019}}
\Description{\MarginText{\textsc{Privatklinik Hirslanden} \\ Zürich.} \vspace{-4mm}
}
\vspace{2.25em} % Extra space between major sections
\datebox=3.2in
\NewEntry{Diverse Praktika}{\textit{07.2015--08.2016}}
\Description{\MarginText{\textsc{} \\ } \vspace{-4mm}
}
\vspace{0.4em} % Extra space between major sections
------------
\vspace{0.4em} % Extra space between major sections
%----------------------------------------------------------------------------------------
% EDUCATION
%----------------------------------------------------------------------------------------
\spacedlowsmallcaps{Ausbildung}\vspace{1em}
\datebox=3.2in
\NewEntry{MSc Psychologie}{\textit{2020-2022}}
\Description{\MarginText{\textsc{UZH} \\ Zürich.}
\vspace{-4mm}
\begin{itemize}
\item Masterarbeit \\ \textit{Englisch als Lingua Franca und Machine Translation}
\end{itemize}}
\datebox=3.2in
\NewEntry{BSc Psychologie}{\textit{2016-2020}}
\Description{\MarginText{\textsc{UZH} \\ Zürich.}
\vspace{-4mm}
}
\datebox=3.2in
\NewEntry{Gymnasiale Maturität}{\textit{2009-2015}}
\Description{\MarginText{\textsc{Kantonsschule} \\ Wetzikon.}
\vspace{-4mm}
\begin{itemize}
\item Schwerpunktfach Spanisch
\end{itemize}
}
%------------------------------------------------
%------------------------------------------------
%------------------------------------------------
%----------------------------------------------------------------------------------------
% OTHER INFORMATION
%----------------------------------------------------------------------------------------
\vspace{1em} % Extra space between major sections
\spacedlowsmallcaps{Verschiedenes}\vspace{1em}
\Description{seit 2017 \ \ ~ $\cdotp$\ \ Vorstand Samariterverein Grüningen}
\vspace{-0.5em} % Negative vertical space to counteract the vertical space between every \Description command
\Description{~~~~~~~~~~~~~~~ \ \ $\cdotp$\ \ Mitglied Verein \href{https://www.njira.org/}{Njira}}
\vspace{-0.5em} % Negative vertical space to counteract the vertical space between every \Description command
\newpage
%------------------------------------------------
%----------------------------------------------------------------------------------------
% COMPUTER SKILLS
%----------------------------------------------------------------------------------------
\spacedlowsmallcaps{Software}\vspace{1em}
\Description{\MarginText{Ausgezeichnet}Microsoft Office Word \& Excel}
\Description{\MarginText{Fortgeschritten} R, \LaTeX, SDL Trados Studio, Adobe Illustrator \& InDesign}
%------------------------------------------------
\vspace{0.8em}
\spacedlowsmallcaps{Sonstiges}\vspace{1em}
\newlength{\langbox} % Create a new length for the length of languages to keep them equally spaced
\settowidth{\langbox}{Französisch} % Length equals the length of "English" - if you have a longer language in your list put it here
\Description{\MarginText{Sprachen}\parbox{\langbox}{\textsc{Deutsch}}\ \ $\cdotp$\ \ \ Muttersprache}
\vspace{-0.5em} % Negative vertical space to counteract the vertical space between every \Description command
\Description{\parbox{\langbox}{\textsc{Englisch}}\ \ $\cdotp$\ \ \ Muttersprache}
\vspace{-0.5em} % Negative vertical space to counteract the vertical space between every \Description command
\Description{\parbox{\langbox}{\textsc{Französisch}}\ \ $\cdotp$\ \ \ B1}
\vspace{-0.5em} % Negative vertical space to counteract the vertical space between every \Description command
\Description{\parbox{\langbox}{\textsc{Russisch}}\ \ $\cdotp$\ \ \ A2}
\vspace{1em} % Negative vertical space to counteract the vertical space between every \Description command
%------------------------------------------------
\Description{\MarginText{Interessen}Fussball\ \ $\cdotp$\ \ Schwimmen \ \ $\cdotp$\ \ Sprache \& Geschichte \ \ $\cdotp$\ \ Typografie \& Drucksatz}
%----------------------------------------------------------------------------------------
\end{cv}
\end{document}

ImageMagick convert to png8 (paletted PNG with binary alpha) using background color for partially transparent pixels

I have a 32-bit PNG image like this:
Displayed here with a checkerboard background for visibility, but instead of the checkerboard the image is actually transparent (for your reference: the original 32-bit image). As you can see, around the edges and towards the right, the red pixels are gradually fading out from opaque to transparent.
If I would display this 32-bit image on top of a blue background, the pixels around the edges and towards the right would gradually fade from red to blue.
Now I need to convert this image to an 8-bit PNG with binary alpha. I want the fully transparent area to remain fully transparent, but the partially transparent pixels to gradually blend with the intended background/matte color, in this example blue.
So something like this:
However, I can't seem to figure out how to do this with ImageMagick (using ImageMagick 7.0.8-26 on Mac). I tried as follows:
magick original.png -background 'rgba(0,0,255,0)' png8:output.png
But this results in:
It seems to ignore the blue background color altogether, and just convert the transparency to binary (probably taking fully opaque for ≥128 or fully transparent for <128).
Also if I specifiy rgb(0,0,255) as background color (i.e. no alpha) the result is the same.
Does ImageMagick have some smart 'background blending for partially transparent pixels' option that I don't know about?
Otherwise, I'm guessing I should somehow extract a binary bitmap where the original image is fully transparent (i.e. has alpha value or opacity 0), then flatten the image on a background of my choosing, and then re-apply the boolean alpha bitmap again. But not quite sure how to do this.
I can think of two techniques, but I'm sure folks have better answers.
First Option
Composite the blue background, and then copy the alpha channel from the original source.
magick original.png \( \
+clone \( +clone -fill BLUE -draw 'color 0,0 reset' \) \
-compose DstOver -composite \) \
-swap 0,1 -compose CopyAlpha -composite PNG8:output.png
Second Option
Replace transparent with blue color, but then call -transparent without any -fuzz operation.
magick original.png \( \
+clone -fill BLUE -draw 'color 0,0 reset' \) \
-compose DstOver -composite -transparent BLUE \
PNG8:output.png
Again, I'm sure the above examples can be improved on. YMMV
One way to do that with ImageMagick is to extract the alpha channel, colorize essentially everything except the totally transparent pixels, and composite the original image over the result.
convert input.png \( +clone -alpha extract -transparent black -fill blue \
-channel RGB -colorize 100 +channel \) +insert -composite output.png
That reads the input image, clones it inside the parentheses, and extracts the alpha channel to a black and white mask.
The pure black is made transparent with "-transparent black".
The white, everything except pure black, is changed to blue with "-colorize 100". Setting "-channel RGB" applies that fill color to only the white part of the mask and ignores the transparent.
Then after the parentheses the "+insert" moves that blue-on-transparent image to the back, and "-composite" places the input image over that blue and transparent one.
If you're using ImageMagick version 7, use "magick" instead of "convert". If you're running on Windows, change the end of line backslash "\" to a caret "^", and remove the backslashes that escape the parentheses "\(...\)" to simply "(...)".
Here is one more way in ImageMagick.
convert img.png \
\( -clone 0 -alpha extract -channel rgba \
\( xc:none xc:blue +append \) -clut +channel \
-channel alpha -threshold 0 +channel \) \
+swap -compose over -composite PNG8:result.png
OR FOR Imagemgick 7
magick img.png \
\( -clone 0 -alpha extract -alpha copy -channel rgba \
\( xc:none xc:blue +append \) -clut \
-channel alpha -threshold 0 +channel \) \
+swap -compose over -composite PNG8:result.png
Read the image.
Clone it, extract the alpha channel, create transparent blue color map and apply to the alpha channel, then threshold the alpha channel.
Swap the two images and composite the original over the processed alpha channel.
Save the output.
Thanks to the posted suggestions, however the problem is I don't want to mask any particular color (like black or blue) as transparent. That exact same color may also appear in the non-transparent parts.
After some tweaking, I got the exact result I need:
magick original.png -write MPR:foo -background 'rgb(0,0,255)' -flatten \( MPR:foo -alpha extract -threshold 0 \) -compose copy_opacity -composite png8:result.png
Explanation:
I start with original.png and use -write MPR:foo to save a temporary copy in memory called 'foo'
Then I flatten the image on a blue background, giving the correct color values everywhere (including blended with the background for partially transparent pixels) but losing the opacity data.
Then I side-process a 2nd layer, opening the same original input image (restoring from memory using MPR:foo) and extract its alpha channel which now becomes a grayscale image, containing the original alpha data.
I apply -threshold 0 on that layer, which changes all channel values that were >0 to the maximum (i.e. alpha 255 or fully opaque) and ≤0 remains 0 (fully transparent). So this is now my 'binary alpha' channel.
Then finally I merge these two layers by using a copy_opacity composite which just copies the 2nd layer (the binary alpha) and writes that as the resulting layer's alpha data.
Saving the end result gives me the exact image I need.

Convert PDF/Images to a flip based effect in GIF

I want to convert a PDF or sequence-of-images to a flip based effect in GIF (similar to the one below).
Is there any softwares available handy I could use to produce this output? or do I have to write scripts using imageMagicK? please suggest?
Thanks in advance!
Cool project! This isn't production-ready, military-hardened, bullet-proof code, but the following will do most of the heavy lifting as regards getting set up, appending the individual pages, distorting pages as they turn and finally putting the whole lot together in an animated GIF sequence.
#!/bin/bash
################################################################################
# flipbook
# Mark Setchell
#
# Give me 4 pages as parameters and I create an animated GIF book out of them
# called book.gif.
#
# Requires ImageMagick
################################################################################
# Names of the 4 pages
p0=${1:-page0.gif} # Use first arg, or "page-0.gif" if none given
p1=${2:-page1.gif}
p2=${3:-page2.gif}
p3=${4:-page3.gif}
# Get width and height of images - I assume, but do not check all are identical sizes
read w h < <(convert "$p0" -format "%w %h" info: )
((twow=w+w))
# Layout first and last flat double-page spreads
convert "$p0" "$p1" +append frame0.png
convert "$p2" "$p3" +append frame4.png
# Make right page taller and thinner and save as "distorted.png"
((deltah=20*h/100))
((deltaw=20*w/100))
((hplusdeltah=h+deltah))
((wminusdeltaw=w-deltaw))
((hplus2deltah=h+deltah+deltah))
points="0,0 0,$deltah $wminusdeltaw,0 $wminusdeltaw,0 $wminusdeltaw,$hplus2deltah $wminusdeltaw,$hplus2deltah 0,$hplus2deltah 0,$hplusdeltah"
convert "$p1" +matte -virtual-pixel transparent \
-resize ${wminusdeltaw}x${hplus2deltah}! +repage \
-distort Perspective "$points" +repage distorted.png
# Make second frame by overlaying distorted right page ontop of pages 0 and 3
convert "$p0" "$p3" +append \
-bordercolor white -border 0x$deltah \
+repage \
distorted.png \
-geometry +${w}x \
-composite frame1.png
# Make left page taller and thinner and save as "distorted.png"
((deltaw=70*w/100))
((wminusdeltaw=w-deltaw))
points="0,0 0,0 $wminusdeltaw,0 $wminusdeltaw,$deltah $wminusdeltaw,$hplus2deltah $wminusdeltaw,$hplusdeltah 0,$hplus2deltah 0,$hplus2deltah"
convert "$p2" +matte -virtual-pixel transparent \
-resize ${wminusdeltaw}x${hplus2deltah}! +repage \
-distort Perspective "$points" +repage distorted.png
# Make third frame by overlaying distorted left page ontop of pages 0 and 3
convert "$p0" "$p3" +append \
-bordercolor white -border 0x$deltah \
+repage \
distorted.png \
-geometry +${deltaw}x \
-composite frame2.png
# Make left page taller and thinner and save as "distorted.png"
((deltaw=20*w/100))
((wminusdeltaw=w-deltaw))
points="0,0 0,0 $wminusdeltaw,0 $wminusdeltaw,$deltah $wminusdeltaw,$hplus2deltah $wminusdeltaw,$hplusdeltah 0,$hplus2deltah 0,$hplus2deltah"
convert "$p2" +matte -virtual-pixel transparent \
-resize ${wminusdeltaw}x${hplus2deltah}! +repage \
-distort Perspective "$points" +repage distorted.png
# Make fourth frame by overlaying distorted right page ontop of pages 0 and 3
convert "$p0" "$p3" +append \
-bordercolor white -border 0x$deltah \
+repage \
distorted.png \
-geometry +${deltaw}x \
-composite frame3.png
# Make final animation from frame0.png...frame4.png
convert -gravity center -delay 100 frame*.png -background white -extent ${twow}x${hplus2deltah} book.gif
So, if you start with the following as page0.gif, page1.gif, page2.gif and page3.gif...
You will get this as book.gif
If your book has more than 4 pages, you can do four at a time and then append the animations quite simply.
Updated Answer
It seems you are unfortunate enough to have to use Windows - which is very cumbersome in BATCH. I am no expert, but can get around in BATCH a little. I think the script above is pretty easy to translate though. I'll get you started but you will need to do some yourself - you can always ask a new question if you get stuck - questions are free!
The first part of the script just picks up the parameters supplied on the command line, so it'll look like this:
REM Pick up commandline parameters
set p0=%1
set p1=%2
set p2=%3
set p3=%4
Then we need to work out the width and height of the input images, something like this:
REM Get width and height of images in variable "w" and "h"
FOR /F %%A IN ('identify -format "w=%%w\nh=%%h" %p0%') DO set %%A
All the stuff in my original script inside ((..)) is just simple maths which can be done in BATCH using SET /A, so the lines that look like this:
((twow=w+w))
((deltah=20*h/100))
will look like this:
SET /A TWOW=w+w
SET /A DELTAH=20*h/100
The rest is just convert commands - you will need to do a couple of things there:
Replace line continuations at ends of lines, so change \ to ^
Where I use $variable or ${variable}, replace it with %variable%
Double any % signs I have, so % becomes %%
Change \( to ^( - I think
change any single quotes ' to double quotes "
Best to just work through it and see what happens as you convert each line and ask another question if you can't work it out.
There is some good info at these places - ss64 - general, ss64 - set command on BATCH in general. Also, an English guy called Alan Gibson, uses IM with Windows very competently and you can see his scripts here, and also more generally here for inspiration on how to be effective with IM under Windows.

Ghostscript renders ugly text

I'm trying to add the capability to render LaTeX equations to a project I'm working on. To do so, I use XeLaTeX to create a PDF file, which I then render to a (transparent) 96dpi-PNG using Ghostscript.
I'd like to have the rendered LaTeX blend in with the rest of the text (which is rendered using standard .NET GDI+ methods, but that's off-topic), but I can't get a reliably "good" text rendering: the output always looks somehow blurry or otherwise "bad".
Example:
From left to right, the same (small) PDF rendered at 96dpi with Ghostscript, Photoshop, and TexWorks (which I understand uses Ghostscript internally).
The command I use to run Ghostscript is the following:
"C:/Program Files (x86)/gs/gs9.09/bin/gswin32c.exe" \
-q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT \
-dMaxBitmap=500000000 -dAlignToPixels=1 -dGridFitTT=2 \
"-sDEVICE=pngalpha" -dTextAlphaBits=4 \
-dGraphicsAlphaBits=4 "-r96" -dFirstPage=1 -dLastPage=1 \
-sOutputFile="output.png" "input.pdf"
(which I actually pretty much copied from the command ImageMagick calls when converting a PDF file, but that's another story). I tried changing any of the relevant options (dAlignToPixels=0, dGridFitTT=0/1/2, dTextAlphaBits=2/4 [or without this parameter altogether]) and I even tried to render the PDF to 4 times the resolution and then downscale it, without any noticeable improvement.
Yet, I'm sure there must be some way of decently rendering the PDF with Ghostscript (since TexWorks does), although I'm unable to find it.
Any hint? The PDF is this one.
You could try to render your PDF at a higher resolution. 96dpi just isn't enough for text with 11 pt size.
If you use 192dpi and then scale the display of the resulting image to 50% (wherever you use the PNG), these parts should still appear in the same size as befor, but with a higher resolution. What used to be a 4x7 pixels 's' should now be a 8x14 pixels 's'...
Update
Ok, since my explanation seems to have been not comprehendible enough for the OP, here's the deal.
Generate a PDF file containing the word "Test", using Ghostscript. In my case, it is Ghostscript v9.10:
gs \
-o test.pdf \
-sDEVICE=pdfwrite \
-g230x100 \
-c "/Helvetica findfont \
11 scalefont \
setfont \
1 1 moveto \
(Test) show \
showpage"
From this PDF, generate 6 different images depicting the word "Test", using 6 different resolutions. The gs is still Ghostscript v9.10 (to be checked with gs -version):
for i in 1 2 3 4 5 6; do \
gs \
-o t$(( ${i} * 96 )).png \
-r$(( ${i} * 96 )) \
-sDEVICE=pngalpha \
-dAlignToPixels=1 \
-dGridFitTT=2 \
-dTextAlphaBits=4 \
-dGraphicsAlphaBits=4 \
t.pdf ; \
done
This will create the following PNGs, as confirmed by ImageMagick's identify command:
identify -format "%f : %Wx%H pixels -- %b filesize\n" t[1-9]*.png
t96.png : 31x13 pixels -- 475B filesize
t192.png : 61x27 pixels -- 774B filesize
t288.png : 92x40 pixels -- 1.1KB filesize
t384.png : 123x53 pixels -- 1.43KB filesize
t480.png : 153x67 pixels -- 1.76KB filesize
t576.png : 184x80 pixels -- 2.01KB filesize
Create a sample LaTeX document and embed the different images side by side and/or line by line. Here is my sample code:
\begin{document}
Test
\includegraphics[height=7.5pt]{t96.png}
\includegraphics[height=7.5pt]{t96.png}
\includegraphics[height=7.5pt]{t192.png}
\includegraphics[height=7.5pt]{t288.png}
\includegraphics[height=7.5pt]{t384.png}
\includegraphics[height=7.5pt]{t480.png}
\includegraphics[height=7.5pt]{t576.png}
Test\\
{}
Test <== real text
\includegraphics[height=7.5pt]{t96.png} <-- 96 dpi figure
\includegraphics[height=7.5pt]{t192.png} <-- 192 dpi figure
\includegraphics[height=7.5pt]{t288.png} <-- 288 dpi figure
\includegraphics[height=7.5pt]{t384.png} <-- 384 dpi figure
\includegraphics[height=7.5pt]{t480.png} <-- 480 dpi figure
\includegraphics[height=7.5pt]{t576.png} <-- 576 dpi figure
Test <== real text
\end{document}
Here is a screenshot (at 400% zoom) from the PDF created via LuaLaTeX from the above LaTeX code:
The line with the 8 "Test" words has actual text only in the first and the last word. The 6 words in between are images with 96, 96, 192, 288, 384, 480 and 576 dpi.
I hope you can see now clearly how scaling up your image generation to a higher resolution will result in better quality for your final PDF if you include the higher resolution images into your LaTeX code...
You are rendering text at 11 points, at 96 dpi, that works out to about 14 pixels in height which, frankly, is not a lot (and in my output the 's' is 7 pixels high by 4 wide). Looking at your output all 3 look 'blurry' and the Photoshop output looks overly bold in the capital T.
If you don't want it blurred, then don't set TextAlphaBits, or don't set it to such a high value.
I'd also suggest using the current release (9.15).

Reducing PDF file size using Ghostscript on Linux didn't work

I have about 50-60 pdf files (images) that are 1.5MB large each. Now I don't want to have such large pdf files in my thesis as that would make downloading, reading and printing a pain in the rear. So I tried using ghostscript to do the following:
gs \
-dNOPAUSE -dBATCH \
-sDEVICE=pdfwrite \
-dCompatibilityLevel=1.4 \
-dPDFSETTINGS="/screen" \
-sOutputFile=output.pdf \
L_2lambda_max_1wl_E0_1_zg.pdf
However, now my 1.4MB pdf is 1.5MB large.
What did I do wrong? Is there some way I can check the resolution of the pdf file? I just need 300dpi images, so would anyone suggest using convert to change the resolution or is there someway I could change the image resolution (reduce it) with gs, since the image is very grainy when I use convert
How I use convert:
convert \
-units PixelsPerInch \
~/Desktop/L_2lambda_max_1wl_E0_1_zg.pdf \
-density 600 \
~/Desktop/output.pdf
Example File
http://dl.dropbox.com/u/13223318/L_2lambda_max_1wl_E0_1_zg.pdf
If you run Ghostscript -dPDFSETTINGS=/screen this is just a sort of shortcut. In fact you'll get (implicitly) a whole bunch of settings used, which you can query with the following command:
gs \
-dNODISPLAY \
-c ".distillersettings {exch ==only ( ) print ===} forall quit" \
| grep '/screen'
On my Ghostscript (v9.06prerelease) I get the following output (slightly edited to increase readability):
/screen
<< /DoThumbnails false
/MonoImageResolution 300
/ColorImageDownsampleType /Average
/PreserveEPSInfo false
/ColorConversionStrategy /sRGB
/GrayImageDownsampleType /Average
/EmbedAllFonts true
/CannotEmbedFontPolicy /Warning
/PreserveOPIComments false
/GrayImageResolution 72
/GrayACSImageDict <<
/ColorTransform 1
/QFactor 0.76
/Blend 1
/HSamples [2 1 1 2]
/VSamples [2 1 1 2]
>>
/ColorImageResolution 72
/PreserveOverprintSettings false
/CreateJobTicket false
/AutoRotatePages /PageByPage
/MonoImageDownsampleType /Average
/NeverEmbed [/Courier
/Courier-Bold
/Courier-Oblique
/Courier-BoldOblique
/Helvetica
/Helvetica-Bold
/Helvetica-Oblique
/Helvetica-BoldOblique
/Times-Roman
/Times-Bold
/Times-Italic
/Times-BoldItalic
/Symbol
/ZapfDingbats]
/ColorACSImageDict <<
/ColorTransform 1
/QFactor 0.76
/Blend 1
/HSamples [2 1 1 2]
/VSamples [2 1 1 2] >>
/CompatibilityLevel 1.3
/UCRandBGInfo /Remove
>>
I'm wondering if your PDFs are image-heavy, and if this sort of conversion does un-welcome things (f.e. re-sampling images with the 'wrong' parameters) which increase the file size...
If this is the case (image-heavy PDF), tell so, and I'll update this answer with a few suggestions....
Update
I had a look at the sample file provided by DNA. Interesting...
No, it does not contain any image.
Instead, it contains one large stream (compressed using /FlateDecode) which consists of roughly 700.000+ (!!) operations, mostly single vector operations in PDF language, such as:
m (moveto),
l (lineto),
d (setdash),
w (setlinewidth),
S (stroke),
s (closepath and stroke),
W* (eoclip),
rg and RG (setrgbcolor)
and a few more.
(That PDF code is very inefficiently written AFAICS (but does its job), because it does concatenate many short strokes instead of doing 'long' ones, and nearly each stroke defines the color again (even if it is the same as before), and has all the other overhead (start stroke, end stroke,...).
Ghostscript's -dPDFSETTINGS=/screen do not have any effect here (there are no images to downsample, for example). The increased file size (+48 kByte to be precise) is probably due to Ghostscript re-organizing some of the internal stroking etc. commands to a different order when it interprets the file.
So there is not much you can do about the PDF file size ...
...unless you convert each of these PDF pages into a REAL image such as PNG:
gs \
-o out72.png \
-sDEVICE=pngalpha \
L_2lambda_max_1wl_E0_1_zg.pdf
(I used the pngalpha output to get transparent background.) The image dimensions of 'out.png' are 259x213px, the filesize is now 70 kByte. But I'm sure you'll not like the quality :-)
The output quality is 'bad' because Ghostscript uses a default resolution of 72 dpi.
Since you said you'd like to have 300dpi, the command becomes this:
gs \
-o out300.png \
-sDEVICE=pngalpha \
-r300 \
L_2lambda_max_1wl_E0_1_zg.pdf
The filesize now is 750 kByte, the image dimensions are 1080x889 Pixels.
Update 2
Since Curiosity is en vogue these days... :-) ...I tried to bring down the file size with the help of Adobe Acrobat X Pro on Mac.
You wanna know the results?
Performing a 'Save as... (PDF with reduced filesize)' -- which for me in the past always yielded very good results! -- created a 1,8++ MByte file (+29%). I guess this definitely puts Ghostscript's performance (file size increase +3%) into a realistic perspective !
DNA decided to go for grayscale PNGs. The way he's creating them is in two steps:
Step 1: Convert a color PDF page (such as this) to a grayscale PDF page, using Ghostscript's pdfwrite device and the settings
-dColorConversionStrategy=/Gray and
-dProcessColorModel=/DeviceGray.
Step 2: Convert the grayscale PDF page to a PNG, using Ghostscript's pngalpha device at a resolution of 300 dpi (-r300 on the GS commandline).
This reduces his initial file size of 1.4 MB to 0.7 MB.
But this workflow has the following disadvantage:
It looses all color info, without saving much disk space as compared to a color output written at the same resolution, directly from the PDF!
There are 2 alternatives to DNA's workflow:
A one-step conversion of (color) PDF -> (color) PNG, using Ghostscript's pngalpha device with the original PDF as input (same settings of 300 dpi resolution). This would have this advantage:
It would keep the color information in the PNG output, requiring only a little more space on disk!
A one-step conversion of (color) PDF -> grayscale PNG, using Ghostscript's pnggray device with the original PDF as input (same settings of 300 dpi resolution), with this mix of advantage/disadvantage :
It would loose the color information in the PNG output.
It would loose the transparent background that was preserved in DNA's workflow.
It would save lots of disk space, because the filesize would go down to about 20% of the output from DNA's workflow.
So you can make up your mind and see the output sizes and quality side-by-side, here is a shell script to demonstrate the differences:
#!/bin/bash
#
# Copywrite (c) 2012 <kurt.pfeifle#gmail.com>
# License: Creative Commons (CC BY-SA 3.0)
function echo_do() {
echo
echo "Command: ${*}"
echo "--------"
echo
"${#}"
}
[ -d out ] || mkdir out
echo
echo " We assume all PDF pages are 1-page PDFs!"
echo " (otherwise we'd have to include something like '%03d'"
echo " into the output filenames in order to get paged output)"
echo
echo '
# Convert Color PDF to Grayscale PDF.
# If PDF has transparent background (most do),
# this will remain transparent in output.)
# ATTENTION: since we don't use a resolution,
# pdfwrite will use its default value of '-r720'.
# (However, this setting will only affect raster objects...)
'
for i in *.pdf
do
echo_do gs \
-o "out/${i}---pdfwrite-devicegray-gs.pdf" \
-sDEVICE=pdfwrite \
-dColorConversionStrategy=/Gray \
-dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 \
"${i}"
done
echo '
# Convert (previously generated) grayscale PDF to PNG using Alpha channel
# (Alpha channel can make backgrounds transparent)
'
for i in out/*pdfwrite-devicegray*.pdf
do
echo_do gs \
-o "out/$(basename "${i}")---pngalpha-from-pdfwrite-devicegray-gs.png" \
-sDEVICE=pngalpha \
-r300 \
"${i}"
done
echo '
# Convert (color) PDF to grayscale PNG using Alpha channel
# (Alpha channel can make backgrounds transparent)
'
for i in *.pdf
do
# Following only required for 'pdfwrite' output device, not for 'pngalpha'!
# -dProcessColorModel=/DeviceGray
echo_do gs \
-o "out/${i}---pngalphagray_gs.png" \
-sDEVICE=pngalpha \
-dColorConversionStrategy=/Gray \
-r300 \
"${i}"
done
echo '
# Convert (color) PDF to (color) PNG using Alpha channel
# (Alpha channel can make backgrounds transparent)
'
for i in *.pdf
do
echo_do gs \
-o "out/${i}---pngalphacolor_gs.png" \
-sDEVICE=pngalpha \
-r300 \
"${i}"
done
echo '
# Convert (color) PDF to grayscale PNG
# (no Alpha channel here, therefor [mostly] white backgrounds)
'
for i in *.pdf
do
echo_do gs \
-o "out/${i}---pnggray_gs.png" \
-sDEVICE=pnggray \
-r300 \
"${i}"
done
echo " All output to be found in ./out/ ..."
echo
Run this script and compare the different outputs side by side.
Yes, the 'direct-grayscale-PNG-from-color-PDF-using-pnggray-device' one may look a bit worse (and it doesn't sport the transparent background) than the other one -- but it is also only 20% of its file size. On the other hand, if you wan to buy a bit more quality by sacrificing a bit of disk space -- you could use -r400 instead of -r300...