1

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

}
}
1

(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',
);
  • sorry for the late reply. I've tried both suggestions and it still gives me a jpg file. – Rich Jul 30 '18 at 20:54
  • 1
    Actually, this part — wp_handle_upload($files, $upload_overrides ); — it should be $file and not $files. But I guess that's just a typo in the question? And can I see the code for the sight() function? – Sally CJ Jul 31 '18 at 1:36
  • 1
    Thanks for sharing the code. I saw why my previous code didn't work for you, but I've updated it, so please check the answer. Let me know how it goes. – Sally CJ Aug 2 '18 at 19:09
  • 1
    @rich I saw (in my email) parts of your previous comments (that you've deleted..), so if you want, I could update the function so that it also accepts a file path as a parameter. Thanks for accepting the answer. :) – Sally CJ Aug 3 '18 at 1:19
  • 1
    Hi Rich. Please check the updated answer. – Sally CJ Dec 3 '18 at 22:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.