Org mode: describe a chess position and automatically generate image of chessboard - emacs

I write articles on chess. I often need to describe a chess position, using a standard format named FEN, and would like it to be automatically converted to a png image, and when I export the org document as LaTeX or html the image to be inlined. I think it can be done because ditaa seems to work similarly.
For example, with the FEN string "8/pppr1kpp/8/8/8/5P2/PPP1RKPP/8 w - - 0 1" as input, I create a tex file named chessboard.tex:
\documentclass[border={0 0 3 0}, convert={density=150}]{standalone}
\usepackage{xskak}
\usepackage{chessboard}
\usepackage{chessfss}
\usepackage{fontspec}
\begin{document}
\setchessboard{normalboard, showmover=true, moverstyle=triangle, label=false}
\setboardfontfamily{merida}
\fenboard{8/pppr1kpp/8/8/8/5P2/PPP1RKPP/8 w - - 0 1} \chessboard
\end{document}
which, with the shell command $> xelatex --shell-escape chessboard.tex, produces the following png image (thanks to the use of the standalone package).
How can I automate this process, so that I could put in an org file something like
#+BEGIN_SRC chessfen
8/pppr1kpp/8/8/8/5P2/PPP1RKPP/8 w - - 0 1
#+END_SRC
and have the above process automated?

Something like this?
#+title: Chess
#+startup: inlineimages
#+property: header-args:latex+ :imagemagick yes :iminoptions -density 300 -resize 400
#+property: header-args:latex+ :headers '("\\usepackage{chessboard}\\usepackage{xskak}\\usepackage{chessfss}") :border 1pt
* Chess
#+begin_src latex :file chess.png :results raw
\setchessboard{normalboard, showmover=true, moverstyle=triangle, label=false}
\fenboard{8/pppr1kpp/8/8/8/5P2/PPP1RKPP/8 w - - 0 1} \chessboard
#+end_src

This modification of rvf0068's answer works for me, after manually installing the necessary LaTeX packages (that can be found by inspecting in the error log output):
#+property: header-args:latex+ :headers '("\\usepackage{chessboard}\\usepackage{xskak}\\usepackage{chessfss}") :border 1pt
#+header: :imagemagick "t"
#+header: :results file raw
#+header: :exports results
#+header: :fit yes :border 0.5cm
#+header: :iminoptions -density 600 :imoutoptions -geometry 600
#+begin_src latex :file alburt_vs_kasparov_1978.png
\setchessboard{normalboard, showmover=false, moverstyle=triangle, label=false}
\fenboard{8/pppr1kpp/8/8/8/5P2/PPP1RKPP/8 w - - 0 1} \chessboard
#+end_src
# Local Variables:
# org-latex-pdf-process: ("xelatex -shell-escape -interaction=nonstopmode -output-directory=%o %f"
# "xelatex -shell-escape -interaction=nonstopmode -output-directory=%o %f"
# "xelatex -shell-escape -interaction=nonstopmode -output-directory=%o %f")
# End:

I use LaTeX environments directly to typeset chess, with no src blocks:
Then, the white brings the king
- to the closest rank to the opposing king and
- to the file one next to that of the opposing king toward the center.
\begin{center}
\fenboard{7k/R7/8/8/8/8/8/7K w - - 0 2}
\mainline{2. Kg2 Kf8 3. Kf3 Ke8 4. Ke4 Kd8 5. Kd5 Kc8 6. Kd6}
\par
\showboard
\end{center}

Related

Package inputenc Error: Unicode character 하 (U+D558) (inputenc) not set up for use with LaTeX. (Automating Unicode Input)

I have read all the related answers around this issue and for most people using \DeclareUnicodeCharacter{}{} works for them. However, I'm generating my TEX file from an input file and I don't know the Unicode characters/words which I'm going to be given in advance, so it would be difficult to use the DeclareUnicodeCharacter declaration.
I'm using pdflatex which some StackExchange answers said wouldn't be as useful for Unicode characters, so I also tried xetex and luatex, but these didn't output as expected. Any suggestions how I could modify my script to output a tex file so that pdflatex will not barf on the Unicode characters? Or one which would be acceptable to xetex or luatex?
I've done simple pdflatex stuff but never used Unicode before.
I'm attempting to modify a script I found on github which generates bingo cards. The original program only dealt with English words in the "squares" input file.
I've added one line to the script in order to get it to see Unicode.
\usepackage[utf8]{inputenc}
the bash script:
#!/usr/bin/bash
## text file which contains bingo squares
input_text=squares
## latex code for center square
center_square='\includegraphics[width=0.9\textwidth]{center.png}'
#center_square=FREE
node=( AA AB AC AD AE BA BB BC BD BE CA CB CD CE DA DB DC DD DE EA EB EC ED EE )
cat > bingo.tex << EOF
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[a4paper,margin=2cm]{geometry}
\usepackage{xstring}
\usepackage[none]{hyphenat}
\usepackage{tikz}
\usetikzlibrary{calc}
\renewcommand{\familydefault}{\sfdefault}
\newcommand{\Size}{3cm}% Adjust size of square as desired
\def\NumOfColumns{5}%
\def\Sequence{1/A, 2/B, 3/C, 4/D, 5/E}% This needs to match \NumOfColumns
\tikzset{Square/.style={
inner sep=0pt,
text width=\Size,
minimum size=\Size,
draw=black,
align=center
}
}
EOF
i=0
OLDIFS=$IFS
IFS=$'\n'
for line in $(sort -R $input_text | head -n 24)
do
echo "\newcommand{\Node${node[i]}}{$line}%" >> bingo.tex
(( i++ ))
done
IFS=$OLDIFS
echo "\newcommand{\NodeCC}{$center_square}%" >> bingo.tex
cat >> bingo.tex << EOF
\pagestyle{empty}
\begin{document}
\centering
% Optional Title
\vspace*{\fill}
\begin{center}
\begin{tikzpicture}[draw=black, ultra thick, x=\Size,y=\Size]
\node at (0.5,-0.8) {\Huge B};
\node at (1.5,-0.8) {\Huge I};
\node at (2.5,-0.8) {\Huge N};
\node at (3.5,-0.8) {\Huge G};
\node at (4.5,-0.8) {\Huge O};
\foreach \col/\colLetter in \Sequence {%
\foreach \row/\rowLetter in \Sequence{%
\pgfmathtruncatemacro{\value}{\col+\NumOfColumns*(\row-1)}
\def\NodeText{\expandafter\csname Node\rowLetter\colLetter\endcsname}
\node [Square] at (\$(\col,-\row)-(0.5,0.5)\$) {\NodeText};
}
}
\end{tikzpicture}
\end{center}
\vspace*{\fill}
\end{document}
EOF
pdflatex bingo.tex
#luatex bingo.tex
#xetex bingo.tex
which generates the following bingo.tex file:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[a4paper,margin=2cm]{geometry}
\usepackage{xstring}
\usepackage[none]{hyphenat}
\usepackage{tikz}
\usetikzlibrary{calc}
\renewcommand{\familydefault}{\sfdefault}
\newcommand{\Size}{3cm}% Adjust size of square as desired
\def\NumOfColumns{5}%
\def\Sequence{1/A, 2/B, 3/C, 4/D, 5/E}% This needs to match \NumOfColumns
\tikzset{Square/.style={
inner sep=0pt,
text width=\Size,
minimum size=\Size,
draw=black,
align=center
}
}
\newcommand{\NodeAA}{주다}%
\newcommand{\NodeAB}{되다}%
\newcommand{\NodeAC}{않다}%
\newcommand{\NodeAD}{것}%
\newcommand{\NodeAE}{보다}%
\newcommand{\NodeBA}{사람}%
\newcommand{\NodeBB}{거}%
\newcommand{\NodeBC}{없다}%
\newcommand{\NodeBD}{나}%
\newcommand{\NodeBE}{아니다}%
\newcommand{\NodeCA}{하다}%
\newcommand{\NodeCB}{그}%
\newcommand{\NodeCD}{수}%
\newcommand{\NodeCE}{이}%
\newcommand{\NodeDA}{있다}%
\newcommand{\NodeDB}{때}%
\newcommand{\NodeDC}{가다}%
\newcommand{\NodeDD}{우리}%
\newcommand{\NodeDE}{같다}%
\newcommand{\NodeCC}{\includegraphics[width=0.9\textwidth]{center.png}}%
\pagestyle{empty}
\begin{document}
\centering
% Optional Title
\vspace*{\fill}
\begin{center}
\begin{tikzpicture}[draw=black, ultra thick, x=\Size,y=\Size]
\node at (0.5,-0.8) {\Huge B};
\node at (1.5,-0.8) {\Huge I};
\node at (2.5,-0.8) {\Huge N};
\node at (3.5,-0.8) {\Huge G};
\node at (4.5,-0.8) {\Huge O};
\foreach \col/\colLetter in \Sequence {%
\foreach \row/\rowLetter in \Sequence{%
\pgfmathtruncatemacro{\value}{\col+\NumOfColumns*(\row-1)}
\def\NodeText{\expandafter\csname Node\rowLetter\colLetter\endcsname}
\node [Square] at ($(\col,-\row)-(0.5,0.5)$) {\NodeText};
}
}
\end{tikzpicture}
\end{center}
\vspace*{\fill}
\end{document}
You can see it output:
\newcommand{\NodeAA}{주다}%
as unicode to be input into the square, but pdflatex doesn't like it.
If you compile with lualatex or xelatex, you'll just have to find a font which has all your glyphs. In the example below, I'm using Arial Unicode MS.
To see which fonts you can use for your glyphes, you can use the command line tool albatross, see https://stackoverflow.com/a/69721465/2777074 for an example how to use it.
% !TeX TS-program = lualatex
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[a4paper,margin=2cm]{geometry}
\usepackage{xstring}
\usepackage[none]{hyphenat}
\usepackage{tikz}
\usetikzlibrary{calc}
\renewcommand{\familydefault}{\sfdefault}
\newcommand{\Size}{3cm}% Adjust size of square as desired
\def\NumOfColumns{5}%
\def\Sequence{1/A, 2/B, 3/C, 4/D, 5/E}% This needs to match \NumOfColumns
\tikzset{Square/.style={
inner sep=0pt,
text width=\Size,
minimum size=\Size,
draw=black,
align=center
}
}
\newcommand{\NodeAA}{주다}%
\newcommand{\NodeAB}{되다}%
\newcommand{\NodeAC}{않다}%
\newcommand{\NodeAD}{것}%
\newcommand{\NodeAE}{보다}%
\newcommand{\NodeBA}{사람}%
\newcommand{\NodeBB}{거}%
\newcommand{\NodeBC}{없다}%
\newcommand{\NodeBD}{나}%
\newcommand{\NodeBE}{아니다}%
\newcommand{\NodeCA}{하다}%
\newcommand{\NodeCB}{그}%
\newcommand{\NodeCD}{수}%
\newcommand{\NodeCE}{이}%
\newcommand{\NodeDA}{있다}%
\newcommand{\NodeDB}{때}%
\newcommand{\NodeDC}{가다}%
\newcommand{\NodeDD}{우리}%
\newcommand{\NodeDE}{같다}%
\newcommand{\NodeCC}{\includegraphics[width=0.9\textwidth]{example-image-duck}}%
\pagestyle{empty}
\usepackage{fontspec}
\setsansfont{Arial Unicode MS}
\begin{document}
\centering
% Optional Title
\vspace*{\fill}
\begin{center}
\begin{tikzpicture}[draw=black, ultra thick, x=\Size,y=\Size]
\node at (0.5,-0.8) {\Huge B};
\node at (1.5,-0.8) {\Huge I};
\node at (2.5,-0.8) {\Huge N};
\node at (3.5,-0.8) {\Huge G};
\node at (4.5,-0.8) {\Huge O};
\foreach \col/\colLetter in \Sequence {%
\foreach \row/\rowLetter in \Sequence{%
\pgfmathtruncatemacro{\value}{\col+\NumOfColumns*(\row-1)}
\def\NodeText{\expandafter\csname Node\rowLetter\colLetter\endcsname}
\node [Square] at ($(\col,-\row)-(0.5,0.5)$) {\NodeText};
}
}
\end{tikzpicture}
\end{center}
\vspace*{\fill}
\end{document}

Ghostscript -- convert PS to PNG, rotate, and scale

I have an application that creates very nice data plots rendered in PostScript with letter size and landscape mode. An example of the input file is at http://febo.com/uploads/blip.ps. [ Note: this image renders properly in a viewer, but the PNG conversion comes out with the image sideways. ] I need to convert these PostScript files into PNG images that are scaled down and rotated 90 degrees for web presentation.
I want to do this with ghostscript and no other external tool, because the conversion program will be used on both Windows and Linux systems and gs seems to be a common denominator. (I'm creating a perl script with a "PS2png" function that will call gs, but I don't think that's relevant to the question.)
I've searched the web and spent a couple of days trying to modify examples I've found, but nothing I have tried does the combination of (a) rotate, (b) resize, (c) maintain the aspect ratio and (d) avoid clipping.
I did find an example that injects a "scale" command into the postscript stream, and that seems to work well to scale the image to the desired size while maintaining the aspect ratio. But I can't find a way to rotate the resized image so that the, e.g., 601 x 792 point (2504 x 3300 pixel) postscript input becomes an 800 x 608 pixel png output.
I'm looking for the ghostscript/postscript fu that I can pass to the gs command line to accomplish this.
I've tried gs command lines with various combinations of -dFIXEDMEDIA, -dFitPage, -dAutoRotatePages=/None, or /All, -c "<> setpagedevice", changing -dDISPLAYWIDTHPOINTS and -dDISPLAYHEIGHTPOINTS, -g[width]x[height], -dUseCropBox with rotated coordinates, and other things I've forgotten. None of those worked, though it wouldn't surprise me if there's a magic combination of some of them that will. I just haven't been able to find it.
Here is the core code that produces the scaled but not rotated output:
## "$molps" is the input ps file read to a variable
## insert the PS "scale" command
$molps = $sf . " " . $sf . " scale\n" . $molps;
$gsopt1 = " -r300 -dGraphicsAlphaBits=4 -dTextAlphaBits=4";
$gsopt1 = $gsopt1 . " -dDEVICEWIDTHPOINTS=$device_width_points";
$gsopt1 = $gsopt1 . " -dDEVICEHEIGHTPOINTS=$device_height_points";
$gsopt1 = $gsopt1 . " -sOutputFile=" . $outfile;
$gscmd = "gs -q -sDEVICE=pnggray -dNOPAUSE -dBATCH " . $gsopt1 . " - ";
system("echo \"$molps\" \| $gscmd");
$device_width_points and $device_height_points are calculated by taking the original image size and applying the scaling factor $sf.
I'll be grateful to anyone who can show me the way to accomplish this. Thanks!
Better Answer:
You almost had it with your initial research. Just set orientation in the gs call:
... | gs ... -dAutoRotatePages=/None -c '<</Orientation 3>> setpagedevice' ...
cf. discussion of setpagedevice in the Red Book, and ghostscript docs (just before section 6.2)
Original Answer:
As well as "scale", you need "rotate" and "translate", not necessarily in that order.
Presumably these are single-page PostScript files?
If you know the bounding box of the Postscript, and the dimensions of the png, it is not too arduous to calculate the necessary transformation. It'll be about one line of code. You just need to ensure you inject it in the correct place.
Chapter 6 of the Blue Book has lots of details
A ubc.ca paper provides some illustrated examples (skip to page 4)
Simple PostScript file to play around with. You'll just need the three translate,scale,rotate commands in some order. The rest is for demonstrating what's going on.
%!
% function to define a 400x400 box outline, origin at 0,0 (bottom left)
/box { 0 0 moveto 0 400 lineto 400 400 lineto 400 0 lineto closepath } def
box clip % pretend the box is our bounding box
clippath stroke % draw initial black bounding box
(Helvetica) findfont 50 scalefont setfont % setup a font
% draw box, and show some text # 100,100
box stroke
100 100 moveto (original) show
% try out some transforms
1 0 0 setrgbcolor % red
.5 .5 scale
box stroke
100 100 moveto (+scaled) show
0 1 0 setrgbcolor % green
300 100 translate
box stroke
100 100 moveto (+translated) show
0 0 1 setrgbcolor % blue
45 rotate
box stroke
100 100 moveto (+rotated) show
showpage
It may be possible to insert the calculated transformation into the gs commandline like this:
... | gs ... -c '1 2 scale 3 4 translate 5 6 rotate' -# ...
Thanks to JHNC, I think I have it licked now, and for the benefit of posterity, here's what worked. (Please upvote JHNC, not this answer.)
## code to determine original size, scaling factor, rotation goes above
my $device_width_points;
my $device_height_points;
my $orientation;
if ($rotation) {
$orientation = 3;
$device_width_points = $ytotal_png_pt;
$device_height_points = $xtotal_png_pt;
} else {
$orientation = 0;
$device_width_points = $xtotal_png_pt;
$device_height_points = $ytotal_png_pt;
}
my $orientation_string =
" -dAutoRotatePages=/None -c '<</Orientation " .
$orientation . ">> setpagedevice'";
## $ps = .ps file read into variable
## insert the PS "scale" command
$ps = $sf . " " . $sf . " scale\n" . $ps;
$gsopt1 = " -r300 -dGraphicsAlphaBits=4 -dTextAlphaBits=4";
$gsopt1 = $gsopt1 . " -dDEVICEWIDTHPOINTS=$device_width_points";
$gsopt1 = $gsopt1 . " -dDEVICEHEIGHTPOINTS=$device_height_points";
$gsopt1 = $gsopt1 . " -sOutputFile=" . $outfile;
$gsopt1 = $gsopt1 . $orientation_string;
$gscmd = "gs -q -sDEVICE=pnggray -dNOPAUSE -dBATCH " . $gsopt1 . " - ";
system("echo \"$ps\" \| $gscmd");
One of the problems I had was that some options apparently don't play well together -- for example, I tried using the -g option to set the output size in pixels, but in that case the rotation didn't work. Using the DEVICE...POINTS commands instead did work.

Caption not displaying table

When I use kable to create a table in my Rnw file, the table outputs as expected. However when I include the caption, the table ceases to output at all. Below is my latex and sample knitr chunk.
\documentclass[titlepage]{article}
\usepackage{graphicx}
\usepackage[dvipsnames]{xcolor}
\usepackage{afterpage}
\usepackage{booktabs}
\usepackage{longtable}
\pagecolor{ForestGreen}\afterpage{\nopagecolor}
\color{white}
\title{%
\noindent\makebox[\linewidth]{\rule{9cm}{0.9pt}}
\huge \textbf{\textit{Key Distributor Report}}\\
\LARGE \vspace{2mm} \textbf{\textit{A detailed quarterly review}} \\
\noindent\makebox[\linewidth]{\rule{9cm}{0.9pt}}
\vspace{6mm} \LARGE Macdonald Corp.}
\pagenumbering{arabic}
\begin{document}
\maketitle
\color{black}
\newpage
\tableofcontents
\newpage
\section{Overview of Key Distributors}
\section{Company A}
\subsection{National Overview}
\subsubsection{Account base structure}
<<
tester, echo=FALSE, message=FALSE, warning=FALSE, results='asis',fig.height=3, fig.width=3, fig.align='center', eval=TRUE >>=
library(knitr)
kable(head(mtcars[,1:3]), booktabs=TRUE, caption='This is a caption')
#
\end{document}
This seems to be a problem of coloring the texts. If you try to select all content in the pdf you realize, that the table is actually there, but the text is white. So simply change the way of coloring the title page (use \color on \maketitle instead of \title):
\documentclass[titlepage]{article}
\usepackage{graphicx}
\usepackage[dvipsnames]{xcolor}
\usepackage{afterpage}
\usepackage{booktabs}
\usepackage{longtable}
\pagecolor{ForestGreen}\afterpage{\nopagecolor}
\title{%
\noindent\makebox[\linewidth]{\rule{9cm}{0.9pt}}
\huge \textbf{\textit{Key Distributor Report}}\\
\LARGE \vspace{2mm} \textbf{\textit{A detailed quarterly review}} \\
\noindent\makebox[\linewidth]{\rule{9cm}{0.9pt}}
\vspace{6mm} \LARGE Macdonald Corp.}
\pagenumbering{arabic}
\begin{document}
{\color{white}%
\maketitle
}
\color{black}
\newpage
\tableofcontents
\newpage
\section{Overview of Key Distributors}
\section{Company A}
\subsection{National Overview}
\subsubsection{Account base structure}
<<tester, echo=FALSE, message=FALSE, warning=FALSE,results='asis',fig.height=3, fig.width=3, fig.align='center', eval=TRUE >>=
library(knitr)
library(kableExtra)
library(dplyr)
kable(head(mtcars[,1:3]), booktabs=T, caption='This is a caption') %>%
kable_styling(latex_options = "hold_position")
#
\end{document}

Gnuplot reading not locale encoding file

I want to plot data of an ISO_8859_1 encoded file (two columns of numbers). Those are the first 10 data points of the file:
#Pe2
1 0.8000
2 0.8000
3 0.8000
4 0.8000
5 0.8000
6 0.8000
7 0.8000
8 0.8000
9 0.8000
10 0.8000
The original file has 15000 data points. I create this data with MATLAB, specifically setting ISO_8859_1 encoding, so I am sure that that's the encoding. This is a snippet of the matlab code:
slCharacterEncoding('ISO-8859-1'); %Instruction before writing anything to the file.
fprintf(fileID,' %7d %7.4f',Tempo(i),y(i)); %For loop in this instruction
fprintf(fileID,'\r'); %Closing the file
fclose(fileID);
This is the script that I run. This file is encoded with the default Windows txt files encoding:
set encoding iso_8859_1
set terminal wxt size 1000,551
# Line width of the axes
set border linewidth 1.5
# Line styles
set style line 1 lc rgb '#dd181f' lt 1 lw 1 pt 0 # red
# Axes label
set xlabel 'tiempo'
set ylabel 'valor'
plot 'Pe2.txt' with lines ls 1
This is the output of the gnuplot console when I run the script. After that I input "show encoding":
G N U P L O T
Version 4.6 patchlevel 5 last modified February 2014
Build System: MS-Windows 32 bit
Copyright (C) 1986-1993, 1998, 2004, 2007-2014
Thomas Williams, Colin Kelley and many others
gnuplot home: http://www.gnuplot.info
faq, bugs, etc: type "help FAQ"
immediate help: type "help" (plot window: hit 'h')
Terminal type set to 'wxt'
gnuplot> cd 'C:\Example'
gnuplot> load 'script.txt'
"script.txt", line 10: warning: Skipping data file with no valid points
gnuplot> plot 'Pe2.txt' with lines ls 1
^
"script.txt", line 10: x range is invalid
gnuplot> show encoding
nominal character encoding is iso_8859_1
however LC_CTYPE in current locale is Spanish_Spain.1252
gnuplot>
If I open the file, make some change undo the change and save the file, gnuplot plots the file. I guess that it's because it saves it with local encoding which is the one gnuplot uses to read files.
How do I plot files with gnuplot which are not with the local encoding format?
I also have what it seems to be a similar problem when I output a file with VS2010Css. If I don't specifically set the culture with:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
I am not able to save a file wich gnuplot is able to plot. I believe that this last problem is because of the "," and the "."
In Css I save the files with this:
StreamWriter Writer = new StreamWriter(dir + #"\" + + (k+1) + "_" + nombre + extension);
Writer.WriteLine("#" + (k+1) + "_" + nombre);
Writer.WriteLine();
Writer.WriteLine("{0,32} {1,32}", "#tiempo", "#valor");
for (int i = 0; i < tiempo.GetLength(0); i++)
{
Writer.WriteLine("{0,32} {1,32}", tiempo[i].ToString(), valor[i, k]);
}
Thank you.
Your file has only carriage returns (\r 0xd) as line breaks which doesn't work with gnuplot. You must use only line feed (\n 0xa), but \r\n does also work.

How to create a layered PSD file from command line?

I need to create a layered PSD file with ImageMagick or any other command-line tool available on Linux platform. Since I need to do this on Linux server, I can't use Photoshop scripting.
The ImageMagick command below creates PSD file with a single layer, where two images (here: plasma fractals) are positioned one below another. (I use ImageMagick 6.5.3-10 2009-07-31 Q16, latest available in MacPorts.)
convert -size 100x100 plasma:fractal plasma:fractal -append out.psd
How do I create a PSD file where each image is in its own layer, and one layer is directly above another?
Or, is there any other command line tool that would allow me to do this?
Update: Any other options than GIMP command line?
If ImageMagick won't work, I'd look at Gimp command line.
The following commands created a 2-layer PSD file for me in the interactive console:
> (gimp-image-new 200 200 0)
(1)
> (gimp-layer-new 1 200 200 0 "layer-1" 100 0)
(2)
> (gimp-layer-new 1 200 200 0 "layer-2" 100 0)
(3)
> (file-psd-save 0 1 0 "test.psd" "test.psd" 0 0)
> (gimp-image-add-layer 1 2 -1)
> (gimp-image-add-layer 1 3 -1)
> (file-psd-save 0 1 1 "test.psd" "test.psd" 0 0)
That would need to be converted into a script-fu script (.scm file) and could be executed from the command-line with something like this:
gimp -i -b '(your-script-name "test.psd" 200 200)' -b '(gimp-quit 0)'
I use the command lines below. I have not encountered any issue in opening the generated PSD in Photoshop, however every layer appears as a background layer, and you have to convert it into a true layer first in order to edit the layer ordering.
Here is the command line for Window. Given the list of images (im1.xxx, im2.xxx etc, im1 being the bottom layer,) a list of labels for the layers ("label1", "label2"...) :
convert ^
( ^
-page +0+0 ^
-label "label1" ^
im1.xxx[0] ^
-background none ^
-mosaic ^
-set colorspace RGB ^
) ^
( ^
-page +0+0 ^
-label "label2" ^
"im2.xxx"[0] ^
-background none ^
-mosaic ^
-set colorspace RGB ^
) ^
( ^
-clone 0--1 ^
-background none ^
-mosaic ^
) ^
-alpha Off ^
-reverse ^
"out.psd"
That is, for each layer, you have something like
( ^
-page +0+0 ^
-label "optional_label" ^
im1.xxx[0] ^
-background none ^
-mosaic ^
-set colorspace RGB ^
)
The label/name of the layer is optional (remove -label if none.) The [0] in im1.xxx[0] retrieves the first image in the image file, in case there exist a thumbnail in the Exif.
On Unix/OSX, you have to protect the parenthesis by a backslash, and the line continuation characters change also to \:
\( \
-page +0+0 \
-label "optional_label" \
im1.xxx[0] \
-background none \
-mosaic \
-set colorspace RGB \
\)
If the image names contain special chars, you can protect them with " (eg "c:\my im1.png") without any issue.
You can use the -adjoin to combine an image sequence.
convert -size 100x100 \
-alpha set plasma:fractal \
-alpha set plasma:fractal \
-adjoin \
out.psd
The alpha channels are needed for the PSD coder.
The order of the images is bottom layer to top layer.
There are a lot of compatibility issues with Photoshop and GIMP depending on the settings.
Using:
ImageMagick 6.5.4-6
Photoshop CS2
Here is some useful links to you:
ImageMagick and PSD images with layers
Some PSD Useful Notes
Psd Layers - ImageMagick Forums
The second link is to use with PHP, but it executes ImageMagick, only use the commands, not the all PHP syntax, only the line of exec code.
Hope i'm helping you!
I agree with Jon Galloway, the Gimp console is a better choice. Here is my script:
(define (pngtopsd width height png-paths psd-path)
(define (add-layers image png-paths)
(if (null? png-paths) 0
(let*
((png (car png-paths))
(new-layer (car (gimp-file-load-layer 0 image (car png)))))
(gimp-image-insert-layer image new-layer 0 -1)
(gimp-item-transform-2d new-layer 0 0 1 1 (cadr png) (caddr png) (cadddr png))
(add-layers image (cdr png-paths))
)
))
(let*
((png (car png-paths))
(image (car (gimp-file-load 1 (car png) (car png))))
(drawable (car (gimp-image-get-active-layer image))))
(gimp-image-resize image width height 0 0)
(gimp-item-transform-2d drawable 0 0 1 1 (cadr png) (caddr png) (cadddr png))
(add-layers image (cdr png-paths))
(file-psd-save 0 image drawable psd-path psd-path 1 0)
(gimp-image-delete image)
))
You just need put this script into file with name "pngtopsd.scm" inside your gimp "script" directory ("c:\Program Files\GIMP 2\share\gimp\2.0\scripts\" for Windows) and you can create layered PSD from list of PNG pictures with transformation (translation or rotation) of each layer. Usage sample:
gimp-console-2.8.exe -i -b ^
"(pngtopsd (list ^
(list \"c:/../1.png\" 0 500 500) ^
(list \"c:/.../2.png\" 0.7 200 1000) ^
(list \"c:/.../3.jpg\" -0.5 1000 0)) ^
\"c:/.../result.psd\")"
There (list \"c:/.../2.png\" 0.7 200 1000) means:
0.7 is the rotation angle of picture (in radians)
200 1000 is x and y shift on an image
You can create a layered PSD with ImageMagick, but note the first image is actually used as the preview image (i.e. composite of all the layers).
convert -size 100x100 plasma:fractal plasma:fractal plasma:fractal out.psd
Will create a 2 layered PSD.