Como montar um .jpg centralizado em um .pdf (usando o tamanho de página e bordas definidas)?

5

Estou procurando converter um .jpg em .pdf, para que o .jpg seja posicionado em um determinado local: centrado em (digamos) uma página A4, com uma borda mínima de 30 pixels ao redor entre a imagem e bordas da página.

Meu ponto de partida é apenas isso (ele apenas cria um PDF do mesmo tamanho que o JPG):

convert image.jpg image.pdf
    
por chris mccoy 25.07.2012 / 17:50

4 respostas

8

Suponho que você queira adicionar uma borda de, digamos, 30px, nos quatro lados. Use a opção -border para o tamanho e -bordercolor para a cor:

convert -border 30 -bordercolor white input.png output.pdf

Mais informações podem ser encontradas aqui: Imagemagick - Adicionando / removendo bordas da imagem

Se você deseja que o PDF final seja de um tamanho específico, use as seguintes opções:

convert \
  -page A4 \
  -gravity northwest \
  -border 30 \
  -bordercolor white \
  input.png output.pdf
    
por 25.07.2012 / 18:45
5

Aqui está um pequeno script que faz o que você quer, e pode fazer isso em vários arquivos .jpg ao mesmo tempo, convertendo cada um em seu próprio arquivo .pdf de uma página.

Salve o script como imgs_to_pdfs.sh e chame-o com um ou vários argumentos de nome de arquivo, assim:

./imgs_to_pdfs.sh myimg1.jpg myimg2.jpg img-*.jpg

Nomes de arquivos de saída corresponderão a nomes de arquivos de entrada com .jpg substituído por .pdf. Portanto, certifique-se de que o script não substitua acidentalmente os arquivos existentes!

Como funciona

  • Para a página para montar a imagem, o script usa o formato A4. Calcula as próprias dimensões A4, uma vez que a palavra-chave A4 aparentemente não é suportada nas versões recentes do ImageMagick.
  • A imagem não é reamostrada ("dimensionada") pelo script, apenas mostrada centralizada com uma certa resolução na tela da página PDF A4. Portanto, nenhuma informação de imagem é perdida por redução de escala e nenhum tamanho de arquivo inútil é adicionado aumentando a escala.
  • Em vez de uma margem mínima de 30 pixels, o script deixa um espaço entre a imagem e as bordas da página em PDF. A vantagem disso ao adicionar uma borda branca à imagem é que ela não é adicionada ao tamanho do arquivo e que você pode extrair a imagem não modificada depois do PDF, se desejar, usando um comando como pdfimages -j file.pdf img .
  • Por padrão, a borda ao redor da imagem será definida como ≥5% de cada dimensão de página. A imagem é dimensionada proporcionalmente para conseguir isso, portanto, as bordas de dimensão x serão de 5% e as bordas de dimensão y serão mais lager, ou vice-versa, dependendo das proporções da imagem. Você pode adaptar o tamanho das bordas adaptando o fator de resolução no script. Atualmente é 1.1 , levando a 110% da resolução para um ajuste de página A4. Portanto, a imagem cobre apenas 90% das dimensões da página A4, deixando duas bordas de 5%. Se você definir o fator para 1.2 , terá duas bordas de 10% e assim por diante.

Outros detalhes

  • Veja a prova de como as fórmulas no script levam a 5% de limites:
    1. O tamanho da página em pixels é calculado como page_size_x = density * 8.27
    2. A densidade é calculada como density = img_size_x / 8.27 * 1.1 . (Isso pressupõe o caso em que a dimensão x precisa da densidade mais alta para deixar uma borda de 5% vazia.)
    3. A linha 2 na linha 1 rende: page_size_x = (img_size_x/8.27*1.1) * 8.27 = img_size_x * 1.1 . Então, de fato, a página é 110% da largura do pixel da imagem, dando duas bordas de 5%.
  • Algumas pessoas parecem precisar de uma operação -repage ( como aqui ) para evitar que o tamanho da página seja ligeiramente "fora". Não foi necessário, mas se você fizer isso, tente -repage ${page_size_x}x${page_size_y} ou -repage A4 como última operação na chamada convert .

Código-fonte do script

#!/bin/bash
# Converts input images to one-page PDF files each, without changing image data.
# The image is centered on a A4 page with a 5% border.

# bc function to calculate maximum of two floats
bc_functions="
define max(a,b) {
  if (a>b) {
    return(a)
  } else {
   return(b)
  }
} ";

for file in "$@"; do \
  # Determine image dimensions in pixels.
  img_size_x=$(identify -format "%w" "$file");
  img_size_y=$(identify -format "%h" "$file");

  # Calculate image density (in dpi) needed to fit the image and a 5% 
  # border all around on an A4 page (8.27x11.69"). Factor 1.1 creates 
  # 2*5% borders, see https://unix.stackexchange.com/a/220114 for details.
  min_density_x=$(echo "$img_size_x/8.27*1.1"  | bc -l);
  min_density_y=$(echo "$img_size_y/11.69*1.1" | bc -l);
  # Use the higher density to prevent any dimension exceeding the required fit.
  density=$(echo "$bc_functions max($min_density_x,$min_density_y)" | bc -l);

  # Calculate canvas dimensions in pixels.
  # (Canvas is an A4 page (8.27x11.69") with the calculated density.)
  page_size_x=$(echo  "8.27*$density" | bc -l);
  page_size_y=$(echo "11.69*$density" | bc -l);

  # Center image on a larger canvas (with a size given by "-extent").
  convert "$file" \
    -gravity center -extent ${page_size_x}x${page_size_y} \
    -units PixelsPerInch -density $density \
    -format pdf -compress jpeg \
    "${file/.jpg/.pdf}";
done;

Referências

por 04.08.2015 / 13:09
1

O que eu finalmente fiz para centralizar a imagem na página com uma borda era especificar a geometria tanto para a página quanto para o redimensionamento e as extensões. Os tamanhos para redimensionar e extensão são reduzidos em 2x o tamanho da borda em ambas as dimensões.

As dimensões dos tamanhos das páginas estão listadas em: link

Para Carta (612 x 792):

convert -page Letter -resize 552x732\> -extent 552x732 -background white -gravity Center -border 30 -bordercolor white image.jpg image.pdf

Para A4 (595x842):

convert -page A4 -resize 535x782\> -extent 535x782 -background white -gravity Center -border 30 -bordercolor white image.jpg image.pdf
    
por 09.03.2016 / 01:06
0

A resposta no link usa a opção -extent , que modifica a imagem de origem, adicionando espaços em branco às bordas.

Esse script usa a opção -page com um deslocamento para redimensionar a tela e posicionar a imagem, o que não modifica as imagens. Consulte o script no Github e copie aqui.

#!/bin/bash
# Converts input images to one-page PDF files each, without changing image data.
# The image is centered on a A4 page with a 5% border.
# Adapted from https://unix.stackexchange.com/a/220114
#
# Usage: [command] image1.jpg image2.png ...
# Output: PDF files named after the images e.g. image1.pdf


# bc function to calculate maximum of two floats
bc_functions="
define max(a,b) {
  if (a>b) {
    return(a)
  } else {
    return(b)
  }
};";

# Do the calculation in string $1 and echo the result.
function calc {
  # Define bc functions so we can use it for the calc.
  echo "$bc_functions $1" | bc -l;
}


for file in "$@"; do \
  # Determine image dimensions in pixels.
  img_size_x=$(identify -format "%w" "$file");
  img_size_y=$(identify -format "%h" "$file");

  # Calculate image density (in dpi) needed to fit the image and a 5% 
  # border all around on an A4 page (8.27x11.69"). Factor 1.1 creates 
  # 2*5% borders, see https://unix.stackexchange.com/a/220114 for details.
  min_density_x=$(calc "$img_size_x / 8.27 * 1.1");
  min_density_y=$(calc "$img_size_y / 11.69 * 1.1");

  # Use the higher density to prevent any dimension exceeding the required fit.
  density=$(calc "max($min_density_x,$min_density_y)");

  # Calculate canvas dimensions in pixels.
  # (Canvas is an A4 page (8.27x11.69") with the calculated density.)
  page_size_x=$(calc "8.27 * $density");
  page_size_y=$(calc "11.69 * $density");

  offset_x=$(calc "($page_size_x - $img_size_x) / 2 * 72 / $density");
  offset_y=$(calc "($page_size_y - $img_size_y) / 2 * 72 / $density");

  # Center image on a larger canvas.
  convert "$file" \
    -page ${page_size_x}x${page_size_y}+${offset_x}+${offset_y} \
    -units PixelsPerInch -density $density \
    -format pdf -compress jpeg \
    "${file/.jpg/.pdf}";
done;

Aqui está um artigo mais detalhado explicando como o script funciona e seu uso.

    
por 15.10.2017 / 01:19