0

Basic info:

So, someone messed up and broke an image-uploading function. The extension . was taken out of the occasion... This means all images got saved like imagejpg instead of image.jpeg.

I figured; No problem, I'll just loop over the folders and rename the files, right? easy peasy;

    public function renameImgs(){
        $dirs = array_filter(glob(DOCROOT.'/uploads/products/*'), 'is_dir');
        foreach($dirs as $dir){
            $files = glob($dir.'/*');
            foreach($files as $file){
                $filename = strtolower($file);
                $newFileName = str_replace('jpg', '.jpg', $filename);
                if(!copy($filename, $newFileName)){
                    echo "failed to copy file: $filename";

                }
                else{
                    unlink($filename);
                }
                //if(imagecreatefromjpeg($filename)){
                    //echo "Can still create image from $filename";
                //}
            }
        }
        echo "done";
    }

I have also tried the rename() function instead of copy(), but that apparently doesn't really matter. Anyway.

The problem

When I do this, all images get corrupted. If I try to open them on my PC after downloading, the image will flash by before telling me it's corrupt. A few came through, though they all have visual corruption.

When I take the backed files (luckily I did back it up) and rename them manually on my PC (windows), the images are perfectly fine. However, we're talking about 1800 images here. I really don't feel like doing this manually when I should be able to just fix it with a script.

The solution (I think)

I feel like I could just rename the file without it being validated in one way or another, it should work?

The imagecreatefromjpeg function didn't come through even once, FYI.

TL;DR

I want to fix the image extensions without breaking them

NoobishPro
  • 2,539
  • 1
  • 12
  • 23
  • Even though there are 1800 images I believe there is software available, perhaps some free, that enables block renaming according to rules. – Andy G Mar 08 '18 at 16:11
  • @AndyG Software that would automatically go through ~1500 seperate folders as well? And place them back into the same folders? – NoobishPro Mar 08 '18 at 16:12
  • 1
    silly question but are the images definitely all JPGs? – ADyson Mar 08 '18 at 16:12
  • @NoobishPro Possibly. I'd search for *block rename* or *advanced rename*. If you are block renaming via a utility you won't have to move them, nor move them back. – Andy G Mar 08 '18 at 16:13
  • [Here's one](https://www.advancedrenamer.com/) that looks pretty. – Andy G Mar 08 '18 at 16:16
  • 2
    `find /path/to/dir -name "*[^.]jpg" -exec rename jpg .jpg {} \;` – Alex Howansky Mar 08 '18 at 16:16
  • I'd use bash for that not php https://stackoverflow.com/questions/21985492/recursively-change-file-extensions-in-bash – jawbonewalk Mar 08 '18 at 16:22
  • @ADyson yes, they're all JPGs. They get converted to JPG automatically on upload. Thanks for the tips guys. I have no experience with bash but I'll try! – NoobishPro Mar 08 '18 at 17:14
  • OK guys, so I went with downloading the images and using the software @AndyG recommended. Thank you so much for this one, it actually worked! If someone could explain to me why my function actually corrupted the images, I guess I would mark that as a true answer? Idk what to do otherwise. – NoobishPro Mar 08 '18 at 17:52
  • I think the problem was caused by your strtolower($file); You are actually changing the complete file path instead of just the file name. – Michael Eugene Yuen Mar 09 '18 at 02:59
  • @MichaelEugeneYuen whelp, it worked perfectly fine path-wise and I don't use any capital letters in folders and files. It's just the images which got corrupted. By now I tested it locally and it worked fine locally as well. – NoobishPro Mar 09 '18 at 14:08

1 Answers1

0

BEFORE

Before

I have tested on windows (xampp) and seems fine to me

<?php
function renameImgs() {

 $mime = array( 
            // images
            'image/png' => 'png',
            'image/jpeg' => 'jpg',
            'image/gif'=> 'gif',
            'image/bmp' => 'bmp',
    );

    $basedir = 'upload';
    foreach (GLOB($basedir .'/*', GLOB_ONLYDIR) as $dir) {
        foreach(GLOB($dir . '/*', GLOB_BRACE) as $img) {
            $path = pathinfo($img)['dirname'];
            // mime_content_type is more reliable
            $ext = $mime[mime_content_type($img)];
            $file = strtolower(basename($img));
            $newname = $path .'/' . preg_replace('/(jpg)|(jpeg)|(gif)|(bmp)/i', '.' . $ext, $file);
            echo $newname;
            if(copy($img, $newname)) {
                unlink($img);
            };
        }
    }
}

renameImgs();
?>

After

Michael Eugene Yuen
  • 2,470
  • 2
  • 17
  • 19
  • Well, the function runs perfectly fine and it does rename the images. The issue is that they are corrupted afterwards. – NoobishPro Mar 08 '18 at 17:35
  • I have tested it with several folders and files and image files are not corrupted – Michael Eugene Yuen Mar 08 '18 at 17:36
  • Whelp, it's been solved now. Strangely enough, using a bit of software to rename them on my pc locally worked perfectly fine. Maybe I should re-try the script locally. That would then show that it's actually somewhat of a server issue, wouldn't it? – NoobishPro Mar 08 '18 at 17:56