web-dev-qa-db-fra.com

Convertir toutes les images au format PNG lors du téléchargement du fichier

Sur mon site, j'ai un formulaire frontal permettant aux utilisateurs de télécharger plusieurs images à l'aide du code suivant: ---

if (!empty($_FILES['vidPix']['tmp_name'][0])) {
                    $i = 1;
                    $files = $_FILES['vidPix'];
                    foreach ($files['name'] as $key => $value) {
                        if ($files['name'][$key]) {
                            $file = array(
                                'name' => $files['name'][$key],
                                'type' => $files['type'][$key],
                                'tmp_name' => $files['tmp_name'][$key],
                                'error' => $files['error'][$key],
                                'size' => $files['size'][$key]
                            );
                            $_FILES = array("sight" . $i => $file);
add_filter( 'upload_dir', 'wpse_141088_upload_dir' );
add_filter('intermediate_image_sizes_advanced', 'no_image_resizing');

                        $mfile =  wp_handle_upload($files, $upload_overrides );                          
                            $newvidPix = sight("sight" . $i, $v_Id);
remove_filter( 'upload_dir', 'wpse_141088_upload_dir' );
remove_filter('intermediate_image_sizes_advanced', 'no_image_resizing');

                            if ($i == 1) {
                                update_post_meta($v_Id, '_thumbnail_id', $newvidPix);
                            }
                                add_post_meta($v_Id, 'vid_pix', $newvidPix, false);
                        }
                        $i++;
                    }
                }

Cela fonctionne bien, mais maintenant je veux faire en sorte que les fichiers soient convertis au format PNG, puis sauvegardés dans le dossier et être débarrassés de l'ancien fichier. J'ai trouvé cette question qui suggère le code suivant -

imagepng(imagecreatefromstring(file_get_contents($file)), "output.png");

Je ne sais pas comment le faire fonctionner avec mon téléchargement cependant. Comment pourrais-je m'y prendre?

UPDATE - POUR LE CHARGEMENT DE FICHIER UNIQUE

if(isset($_POST["ebc_submit"])) {

    $uploadedfile2 = $_FILES ['ebc_upload'];
    if (! empty ( $uploadedfile2 ['name'] )) {
        $upload_overrides = array (
            'test_form' => false 
        );

add_filter( 'upload_dir', 'wpse_141088_upload_dir' );
add_filter('intermediate_image_sizes_advanced', 'no_image_resizing');

                        $endpic = wp_handle_upload($uploadedfile2, $upload_overrides );

remove_filter( 'upload_dir', 'wpse_141088_upload_dir' );
remove_filter('intermediate_image_sizes_advanced', 'no_image_resizing');

    $im = imagecreatefromstring( file_get_contents( $endpic['file'] ) );
    if ( false !== $im ) {
        $filename = pathinfo( $endpic['file'], PATHINFO_FILENAME );
        $to = dirname( $endpic['file'] ) . '/' . $filename . '.png';

        // Creates the image and saves it in `$to`.
        imagepng( $im, $to );

        // Frees the image from memory.
        imagedestroy( $im );

        // Deletes the original file.
        unlink( $endpic['file'] );

}
// Convert the image to PNG and delete the old image.
attachment_to_png( $uploadedfile2 );

}
}
1
Rich

(réponse mise à jour)

La fonction sight() télécharge non seulement l'image, mais crée également une pièce jointe (c'est-à-dire une publication de type attachment); par conséquent, j'ai mis à jour le code - il est maintenant dans une function nommée attachment_to_png et qu'il utilise la get_attached_file() pour obtenir le fichier image attaché à cette pièce jointe et la update_attached_file() pour mettre à jour le chemin du fichier.

Alors s'il vous plaît suivez ces étapes:

  1. Ajoutez ceci au fichier functions.php du thème:

    function attachment_to_png( $att_id ) {
        $file = get_attached_file( $att_id );
        if ( ! $file ) {
            return false;
        }
    
        // Check MIME and make sure it's not already a PNG image.
        $mime = strtolower( mime_content_type( $file ) );
        if ( ! preg_match( '#^image/([a-z]{3,})$#', $mime, $m ) ||
            'png' === $m[1]
        ) {
            return false;
        }
    
        $im = imagecreatefromstring( file_get_contents( $file ) );
        if ( false !== $im ) {
            $filename = pathinfo( $file, PATHINFO_FILENAME );
            $to = dirname( $file ) . '/' . $filename . '.png';
    
            // Creates the image and saves it in `$to`.
            imagepng( $im, $to );
    
            // Frees the image from memory.
            imagedestroy( $im );
    
            // Deletes the original file.
            unlink( $file );
    
            // Update the attached file.
            update_attached_file( $att_id, $to );
        }
    }
    
  2. Ajoutez ceci après la remove_filter('intermediate_image_sizes_advanced', 'no_image_resizing');:

    // Convert the image to PNG and delete the old image.
    attachment_to_png( $newvidPix );
    

Remarque additionnelle

Je ne pense pas que cela soit nécessaire .. vous devriez donc simplement l'enlever ...

$mfile =  wp_handle_upload($files, $upload_overrides );

À JOUR 03 décembre 2018 UTC

(mis à jour pour le téléchargement de fichier unique)

  1. Vous ne devriez pas utiliser la substance $im et simplement utiliser la fonction attachment_to_png(). Et appelez la fonction comme suit: attachment_to_png( 123 )123 est l’ID de la pièce jointe.

  2. Utilisez media_handle_upload() qui crée une publication en pièce jointe pour l’image téléchargée, et non wp_handle_upload().

Alors essayez ceci:

if ( isset( $_POST["ebc_submit"] ) ) {
    $uploadedfile2 = $_FILES['ebc_upload'];
    if ( ! empty( $uploadedfile2['name'] ) ) {
        $upload_overrides = array(
            'test_form' => false
        );

        add_filter( 'upload_dir', 'wpse_141088_upload_dir' );
        add_filter( 'intermediate_image_sizes_advanced', 'no_image_resizing' );

        // Load media_handle_upload() and other media/image/file functions.
        require_once ABSPATH . 'wp-admin/includes/media.php';
        require_once ABSPATH . 'wp-admin/includes/image.php';
        require_once ABSPATH . 'wp-admin/includes/file.php';

        // $v_Id is the ID of the post where the image should be attached to.
        $endpic = media_handle_upload( 'ebc_upload', $v_Id, array(), $upload_overrides );

        remove_filter( 'upload_dir', 'wpse_141088_upload_dir' );
        remove_filter( 'intermediate_image_sizes_advanced', 'no_image_resizing' );

        // Convert the image to PNG and delete the old image.
        if ( $endpic && ! is_wp_error( $endpic ) ) {
            attachment_to_png( $endpic );
            //echo 'Success!';
        }
    }
}

MIS À JOUR 5 décembre 2018 UTC

Si vous êtes sûr à 100% que not utilisera des noms de fichiers uniques; c.-à-d. lorsque vous téléchargez une image portant le même nom qu'une image précédemment téléchargée, vous pouvez créer une fonction de rappel qui sera utilisée par wp_unique_filename(), dans lequel vous renvoyez le nom de fichier d'origine (mais désinfecté), comme suit:

// Add this to the theme's functions.php
function no_unique_filename( $dir, $name, $ext ) {
    return $name;
}

Et ensuite, dans le $upload_overrides (voir la mise à jour précédente), ajoutez unique_filename_callback comme suit:

$upload_overrides = array(
    'test_form'                => false,
    'unique_filename_callback' => 'no_unique_filename',
);
1
Sally CJ