Executando verificação de segurança...
2

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');
        }
    }
});
Carregando publicação patrocinada...