Simplificando a Experiência do Usuário: Como Adicionar Botões de Download e Cópia de Imagem em Qualquer Sistema
Durante o desenvolvimento de certa funcionalidade do sistema, um cliente solicitou a possibilidade de copiar o QR Code de PIX para enviá-lo via WhatsApp/Telegram ou simplesmente fazer o download da imagem. Sabemos que é possível copiar e fazer download usando o botão direito do mouse, mas, como sempre, o objetivo é facilitar a vida do usuário.
Neste cenário, eu tinha em mãos a URL de uma imagem, que era fornecida por um serviço de terceiros:https://pix.empresa.com.br/qr/70829075-...-d2041d002f90?type=png
O desafio aqui foi que o servidor onde a imagem estava hospedada recusava o acesso direto, resultando em erros de CORS (Cross-Origin Resource Sharing). Por isso, tive que converter a imagem da URL para base64 para que pudesse manipulá-la localmente. Abaixo está o código que desenvolvi para atender a essa necessidade, utilizando PHP e JavaScript:
<?php
// Definindo as opções do contexto HTTP, incluindo um User-Agent para evitar bloqueios por parte do servidor.
$options = array(
'http' => array(
'header' => "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
)
);
$b64image = NULL;
// Criando o contexto de stream com as opções definidas.
$context = stream_context_create($options);
// Obtendo o conteúdo da imagem a partir da URL, utilizando o contexto criado para evitar bloqueios CORS.
$image = file_get_contents($pix['url'], false, $context);
if($image){
// Convertendo a imagem para uma string base64.
$b64image = 'data:image/png;base64,' . base64_encode($image);
}
?>
<img src="<?= $pix['url']; ?>" alt="..." width="340" id="pix-img" />
<?php if(!is_null($b64image)){ ?>
<!-- Botão para download da imagem já convertida para base64 -->
<a class="btn" download="pix-pedido-"<?= time() ?>.png" href="<?= $b64image ?>">Download</a>
<!-- Botão para copiar a imagem para a área de transferência -->
<button type="button" data-img64="<?=$b64image?>" class="btn" id="copy-img-btn">Copiar Imagem</button>
<?php } ?>
Ao adicionar essas etapas, consegui superar a restrição de CORS, permitindo que a imagem fosse processada e manipulada diretamente no servidor. Isso garantiu que tanto o download quanto a cópia para a área de transferência funcionassem conforme esperado.
Além do código PHP, também foi necessário adicionar a lógica para copiar a imagem para a área de transferência usando JavaScript:
document.addEventListener('DOMContentLoaded', async function() {
const copyImgBtn = document.getElementById('copy-img-btn');
copyImgBtn.addEventListener('click', (e) => {
e.preventDefault();
copyClipboard(copyImgBtn.dataset.img64);
});
async function copyClipboard(base64Image) {
try {
// Verificar e remover o prefixo "data:image/png;base64,"
const base64Data = base64Image.split(',')[1];
// Converter a string Base64 para um Blob
const byteCharacters = atob(base64Data);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: 'image/png' });
// Copiar a imagem para a área de transferência
await navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
console.log('Imagem copiada para a área de transferência.');
} catch (error) {
console.error(error);
alert('Algo de errado aconteceu, clique no botão de Download');
}
}
});