Este script permite a distribuição de páginas coloridas de um documento a ser impresso numa impressora colorida e as página preto/branco na impressora correspondente. É necessária a instalação do ImageMajick, sed e awk.
Para executar:
colorpages.sh <arquivo> <tipo de impressão>
<arquivo>: Localização do arquivo a ser impresso<tipo de impressão>: rascunho : Páginas coloridas consecutivas são impressas frente e verso. O mesmo ocorre para páginas preto e branco. Se uma página é preto e branco e a seguinte é colorida, elas são impressas em folhas separadastese : Páginas consecutivas Ímpar/Par são impressas frente e verso. As páginas consecutivas coloridas serão impressas na impressora a cor e as preto e branco na respectiva impressora. Se uma página ímpar é preto e branco e a seguinte é colorida, serão, primeiramente impressas as páginas preto e branco. O usuário deve retirá-las e colocá-las em ordem dentro da impressora colorida. Recomendada quando a impressora colorida usa mistura de cores para gerar pretolazy : Semelhante a 'tese', mas o usuário não retira o restante da impressora PB. Aqui, as páginas Ímpar/Par que possuam um lado colorido e outro PB são impressas na impressora colorida. Se a impressora colorida possui toner próprio para preto, fica mais simples usar esta opção.OBS: Não testei com arquivos que não estejam em formato PDF.
Dois arquivos são necessários: colorpages.sh e alg.awk.
#!/bin/bash
function colorpages {
file="$1"
i=0;
j=0;
for page in $(identify -format '%p ' "$file") ; do
if [ -n "`convert "$file[$((page-1))]" -colorspace RGB -unique-colors txt:- | sed -e 1d | awk -f alg.awk | head -n 1`" ]
then
COLOR[i]=$page;
i=$((i+1))
else
BW[j]=$page;
j=$((j+1))
fi
done
}
function printArray {
declare -a ARR=("${!1}")
TAM=${#ARR[@]}
for ((k=0;k<$((TAM-1));k++))
do
echo -n ${ARR[k]}","
done
if [ $TAM -gt 0 ]; then
echo -n ${ARR[$((TAM-1))]}
fi
}
function divideSingleDouble {
declare -a ARR=("${!1}")
ARR_DOUBLE=( )
ARR_SINGLE=( )
TAM=${#ARR[@]}
declare -i ind=0
declare -i ind2=0
for ((k=0;k<$TAM;))
do
if [ "${ARR[$((k+1))]}" == $((${ARR[$k]}+1)) ];
then
ARR_DOUBLE[$ind1]=${ARR[$k]}
ARR_DOUBLE[$((ind1+1))]=${ARR[$((k+1))]}
ind1=$((ind1+2))
k=$((k+2));
else
ARR_SINGLE[$ind2]=${ARR[$k]}
ind2=$((ind2+1))
k=$((k+1));
fi
done
}
function divideSingleDoubleOdd {
declare -a ARR=("${!1}")
ARR_DOUBLE=( )
ARR_SINGLE=( )
TAM=${#ARR[@]}
declare -i ind=0
declare -i ind2=0
for ((k=0;k<$TAM;))
do
if [ $((${ARR[$k]} % 2)) == 1 -a "${ARR[$((k+1))]}" == $((${ARR[$k]}+1)) ];
then
ARR_DOUBLE[$ind1]=${ARR[$k]}
ARR_DOUBLE[$((ind1+1))]=${ARR[$((k+1))]}
ind1=$((ind1+2))
k=$((k+2));
else
ARR_SINGLE[$ind2]=${ARR[$k]}
ind2=$((ind2+1))
k=$((k+1));
fi
done
}
function createCOLORandBWpages {
divideSingleDouble COLOR[@]
COLOR_DOUBLE=(${ARR_DOUBLE[@]})
COLOR_SINGLE=(${ARR_SINGLE[@]})
divideSingleDouble BW[@]
BW_DOUBLE=(${ARR_DOUBLE[@]})
BW_SINGLE=(${ARR_SINGLE[@]})
}
function createCOLORandBWpagesOdd {
divideSingleDoubleOdd COLOR[@]
COLOR_DOUBLE=(${ARR_DOUBLE[@]})
COLOR_SINGLE=(${ARR_SINGLE[@]})
divideSingleDoubleOdd BW[@]
BW_DOUBLE=(${ARR_DOUBLE[@]})
BW_SINGLE=(${ARR_SINGLE[@]})
}
function printHelp {
echo "colorpages.sh <arquivo> <tipo de impressão>"
echo " arquivo: Localização do arquivo a ser impresso"
echo " tipo de impressão: "
echo " - rascunho : Páginas coloridas consecutivas são impressas frente e verso"
echo " O mesmo ocorre para páginas preto e branco. Se uma página é"
echo " preto e branco e a seguinte é colorida, elas são impressas"
echo " em folhas separadas"
echo " - tese : Páginas consecutivas Ímpar/Par são impressas frente e verso. As"
echo " páginas consecutivas coloridas serão impressas na impressora a"
echo " cor e as preto e branco na respectiva impressora. Se uma página"
echo " ímpar é preto e branco e a seguinte é colorida, serão, primeira-"
echo " mente impressas as páginas preto e branco. O usuário deve reti-"
echo " rá-las e colocá-las em ordem dentro da impressora colorida. Re-"
echo " comendada quando a impressora colorida usa mistura de cores para"
echo " gerar preto"
echo " - lazy : Semelhante a 'tese', mas o usuário não retira o restante da im-"
echo " pressora PB. Aqui, as páginas Ímpar/Par que possuam um lado co-"
echo " lorido e outro PB são impressas na impressora colorida. Se a im-"
echo " pressora colorida possuir toner próprio para preto, fica mais"
echo " simples usar esta opção."
}
function testando {
TAM=50
declare -i ind1=0
declare -i ind2=0
for((k=1;k<=$TAM;k++))
do
if [ $RANDOM -lt $((32767*25/100)) ]
then
COLOR[$ind1]=$k;
ind1=$((ind1+1));
else
BW[$ind2]=$k;
ind2=$((ind2+1));
fi
done
}
function mergeCOLORandBW_SINGLE {
declare -a ARR1=(${COLOR[@]});
declare -a ARR2=(${BW_SINGLE[@]});
TAM1=${#ARR1[@]}
TAM2=${#ARR2[@]}
N=$((${#BW[@]}+${#COLOR[@]}));
# N pode ser par ou ímpar
# Se for par, BW_SINGLE e COLOR terão tamanhos iguais
# Se for ímpar, apenas um entre COLOR e BW_SINGLE
# será ímpar. Se for BW_SINGLE, ele tem um elemento a mais
# que COLOR.
if [ $((N % 2)) == 1 -a $((TAM2 % 2)) == 1 ]; then
BW_SINGLE=(${ARR2[$((TAM2-1))]})
else
BW_SINGLE=()
fi
COLOR_DOUBLE=();
#Aqui é semelhante ao Merge do Mergesort
for ((k=0;k<TAM1;k++))
do
if [ "${ARR1[k]}" != "" -a "${ARR2[k]}" != "" ]; then
if [ ${ARR1[k]} -lt ${ARR2[k]} ]; then
COLOR_DOUBLE[$((k*2))]=${ARR1[k]}
COLOR_DOUBLE[$((k*2+1))]=${ARR2[k]}
else
COLOR_DOUBLE[$((k*2))]=${ARR2[k]}
COLOR_DOUBLE[$((k*2+1))]=${ARR1[k]}
fi
fi
done
#se COLOR for maior que BW_SINGLE, adicionar o último a COLOR
if [ $TAM2 -lt $TAM1 ]; then
COLOR_DOUBLE[$((2*TAM1))]=${COLOR[$((TAM1-1))]}
fi
COLOR_SINGLE=();
}
COLOR_PRINTER=matisse
BW_PRINTER=degas
if [ "$1" == "" -o "$2" == "" ]; then
printHelp;
exit;
fi
colorpages $1
### Descomente abaixo para depuração ###
# testando; echo BW = ${BW[@]}; echo COLOR = ${COLOR[@]};
### Fim Depurapção ###
if [ $2 == "rascunho" ]; then
createCOLORandBWpages;
elif [ $2 == "tese" ]; then
createCOLORandBWpagesOdd;
elif [ $2 == "lazy" ]; then
divideSingleDoubleOdd BW[@]
BW_DOUBLE=(${ARR_DOUBLE[@]})
BW_SINGLE=(${ARR_SINGLE[@]})
mergeCOLORandBW_SINGLE;
else
printHelp;
exit;
fi
#Print Double Sided Color Pages
if [ ${#COLOR_DOUBLE[@]} -gt 0 ]; then
lpr -P $COLOR_PRINTER -o page-ranges=`printArray COLOR_DOUBLE[@]` -o Duplex=DuplexNoTumble $1;
fi
#Print Double Sided BW Pages
if [ ${#BW_DOUBLE[@]} -gt 0 ]; then
lpr -P $BW_PRINTER -o page-ranges=`printArray BW_DOUBLE[@]` -o Duplex=DuplexNoTumble $1;
fi
#Print Single Sided BW Pages
if [ ${#BW_SINGLE[@]} -gt 0 ]; then
lpr -P $BW_PRINTER -o page-ranges=`printArray BW_SINGLE[@]` -o Duplex=None $1;
fi
if [ $2 == "rascunho" -o $2 == "lazy" ]; then
#Print Single Sided Color Pages
if [ ${#COLOR_SINGLE[@]} -gt 0 ]; then
lpr -P $COLOR_PRINTER -o page-ranges=`printArray COLOR_SINGLE[@]` -o Duplex=None $1;
fi
elif [ $2 == "tese" ]; then
#Print Single Sided Color Pages
if [ ${#COLOR_SINGLE[@]} -gt 0 ]; then
echo
echo "+-------------------------------------------------------------------------+"
echo "| Coloque as páginas com verso em branco da impressora preto e branco (as |"
echo "| últimas que saíram) na impressora colorida. Depois de colocadas, aperte |"
echo "| ENTER para começar a impressão no verso delas. |"
echo "+-------------------------------------------------------------------------+"
read;
lpr -P $COLOR_PRINTER -o page-ranges=`printArray COLOR_SINGLE[@]` -o Duplex=None $1;
fi
else
printHelp;
exit;
fi
{
match($0,/\(\ *[0-9]+,\ *[0-9]+,\ *[0-9]+\)/);
STR=substr($0,RSTART+1,RLENGTH-2);
split(STR, A,",")
mean=(A[1]+A[2]+A[3])/3
a_mean1 = A[1]-mean;
a_mean2 = A[2]-mean;
a_mean3 = A[3]-mean;
value=sqrt(a_mean1*a_mean1 + a_mean2*a_mean2 + a_mean3*a_mean3);
if (value > 653) {print $0}
}
O script colorpages.sh possui dois array principais: BW e COLOR, a lista das páginas preto/branco e coloridas de um arquivo, respectivamente. As funções printBW e printCOLOR imprimem este vetores com seus elementos separados por vírgulas.
A função colorpages carrega o arquivo dado como argumento e preenche BW e COLOR com as páginas preto/branco e coloridas, respectivamente. Para cada página do arquivo PDF, ele lista todos os pixels únicos da página em formato RGB (usando convert do ImageMajick).
Os valores RGB são representados em valores de 0 a 65355. Para verificar se existe páginas coloridas, verifica-se se existe algum pixel cujos valores possuem desvio padrão maior que 653 (1% do valor máximo permitido).
O código alg.awk realiza esta verificação.
Os vetores BW e COLOR a depender da opção fornecida pode ser dividido em dois vetores cada. BW é dividido em BW_DOUBLE, que possui pares de números consecutivos e BW_SINGLE, formado pelos números que sobraram, ordenados, de BW (ou seja, BW_SINGLE = BW - BW_DOUBLE). Similarmente ocorre com COLOR, COLOR_SINGLE e COLOR_DOUBLE.
Se a opção fornecida for tese ou lazy, os vetores _DOUBLE devem ser formados por duplas de números começados por números ímpares. Na opção rascunho, não é necessário. Isto ocorre porque em teses as folhas começam com números ímpares.
O código foi escrito de tal forma que no máximo quatro jobs sejam enviados para as duas impressoras. É fornecido a cada job as listas das páginas a serem impressas, a impressora correspondente e se é para ser impresso frente e verso ou um lado apenas.