最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Convert all images to PNG on file upload

programmeradmin0浏览0评论

On my site I have a front end form for users to upload multiple images, using the following code ---

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++;
                    }
                }

This works fine but now I want to make it so that the files are converted to PNG, then saved to the folder and getting rid of the old file. I found this question that suggests the following code -

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

Im not sure how to get it work with my upload though. How would I go about this?

UPDATE - FOR SINGLE FILE UPLOAD

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 );

}
}

On my site I have a front end form for users to upload multiple images, using the following code ---

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++;
                    }
                }

This works fine but now I want to make it so that the files are converted to PNG, then saved to the folder and getting rid of the old file. I found this question that suggests the following code -

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

Im not sure how to get it work with my upload though. How would I go about this?

UPDATE - FOR SINGLE FILE UPLOAD

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 );

}
}
Share Improve this question edited Dec 3, 2018 at 21:27 730wavy asked Jul 5, 2018 at 2:21 730wavy730wavy 1931 gold badge13 silver badges45 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

(Updated answer)

The sight() function not only uploads the image, but also creates an attachment (i.e. a post of the attachment type); hence, I updated the code — it's now in a function named attachment_to_png, and that it uses the get_attached_file() to get the image file attached to that attachment, and the update_attached_file() to update the file path.

So please follow these steps:

  1. Add this to the theme's functions.php file:

    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. Add this after the remove_filter('intermediate_image_sizes_advanced', 'no_image_resizing');:

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

Additional Note

I don't think this is needed.. so you should just remove it...

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

UPDATED Dec 03 2018 UTC

(Updated for the single file upload)

  1. You shouldn't use the $im stuff and simply use the attachment_to_png() function. And call the function like so: attachment_to_png( 123 ) where 123 is the attachment ID.

  2. Use media_handle_upload() which creates an attachment post for the uploaded image, and not wp_handle_upload().

So try this:

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!';
        }
    }
}

UPDATED Dec 05 2018 UTC

If you're 100% sure about not going to be using unique file names; i.e. when you upload an image with the same name as a previously uploaded image, then you can create a callback function which will be used by wp_unique_filename(), where you return the original (but sanitized) file name, like so:

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

And then, in the $upload_overrides (see previous update), add unique_filename_callback like so:

$upload_overrides = array(
    'test_form'                => false,
    'unique_filename_callback' => 'no_unique_filename',
);
发布评论

评论列表(0)

  1. 暂无评论