716

I need to upload only image file through <input type="file"> tag.

Right now, it accepts all file types. But, I want to restrict it to only specific image file extensions which include .jpg, .gif, etc.

How can I achieve this functionality?

2
  • What's the technology used server-side?
    – Erdal G.
    Dec 19, 2015 at 13:38
  • 7
    <input type='file' accept='image/*'> Jan 11, 2022 at 17:50

13 Answers 13

1650

Use the accept attribute of the input tag. To accept only PNG's, JPEG's and GIF's you can use the following code:

<label>Your Image File
  <input type="file" name="myImage" accept="image/png, image/gif, image/jpeg" />
</label>

Or simply:

<label>Your Image File
  <input type="file" name="myImage" accept="image/*" />
</label>

Note that this only provides a hint to the browser as to what file-types to display to the user, but this can be easily circumvented, so you should always validate the uploaded file on the server also.

It should work in IE 10+, Chrome, Firefox, Safari 6+, Opera 15+, but support is very sketchy on mobiles (as of 2015) and by some reports, this may actually prevent some mobile browsers from uploading anything at all, so be sure to test your target platforms well.

For detailed browser support, see http://caniuse.com/#feat=input-file-accept

10
  • 24
    Are you sure it's image/x-png? According to this list, it is just image/png. iana.org/assignments/media-types/media-types.xhtml
    – Micros
    Aug 27, 2015 at 8:47
  • 4
    Probably it work when the answer was answer, but just tried it and didn´t work for FF. I just needed to add accept=".png, .jpg, .jpeg" E.g: jsfiddle.net/DiegoTc/qjsv8ay9/4
    – Diego
    Oct 15, 2016 at 22:46
  • 1
    If i want to block file type drop down displayed after file name. How can i achieve this? Because if i choose All Types option from drop down then all files are accepted. Nov 13, 2017 at 10:34
  • 6
    Don't rely on it completely. It can easily accept other files too. You just need to change the type of file allowed in the open file window.
    – user8158111
    Mar 9, 2018 at 9:02
  • 3
    I've added the suggested option for png. jpeg and gif, but now the Chrome "open file" dialog shows "Custom Files (*.png; *.jfif; *.pjpeg; *.jpeg; *.pjp; *.jpg)" when I didn't add half of those extensions. I realise that they are mostly the same, but the server doesn't accept those options, and I want to keep it simple for the user. Anyone know what that's about? Sep 14, 2021 at 13:24
229

Using this:

<input type="file" accept="image/*">

works in both FF and Chrome.

6
  • 30
    The accept attribute is not a validation tool, all uploads should be validated on the server, always...
    – TlonXP
    Mar 23, 2015 at 20:35
  • 1
    still not supported in native android browser, but works on others well I guess caniuse.com/#feat=input-file-accept
    – mcy
    Mar 14, 2016 at 11:35
  • I like this solution because in the file prompt the type dropdown shows "Image Files". Jan 11, 2018 at 23:47
  • 3
    Be careful with this, because it allows SVGs, which you might not want. May 19, 2018 at 17:18
  • This will allow maximum image files .png, .jpg, .jpeg, .gif, .bmp, .ico, .tiff, .svg, .ai, .psp, .pcd,.pct, .raw. So it is better to mention type specifically.
    – Thamarai T
    Mar 29, 2019 at 11:24
114

Use it like this

<input type="file" accept=".png, .jpg, .jpeg" />

It worked for me

https://jsfiddle.net/ermagrawal/5u4ftp3k/

2
  • This doesn't work for iOS 12. User can still choose video in device. Jun 2, 2019 at 8:46
  • This works for, at least Google Chrome (other web browsers not yet tested). If you use accept="image/png, image/gif, image/jpeg", Chrome still displays all image types for user to select. See Mozilla Doc. Oct 17, 2022 at 9:15
57

Steps:
1. Add accept attribute to input tag
2. Validate with javascript
3. Add server side validation to verify if the content is really an expected file type

For HTML and javascript:

<html>
<body>
<input name="image" type="file" id="fileName" accept=".jpg,.jpeg,.png" onchange="validateFileType()"/>
<script type="text/javascript">
    function validateFileType(){
        var fileName = document.getElementById("fileName").value;
        var idxDot = fileName.lastIndexOf(".") + 1;
        var extFile = fileName.substr(idxDot, fileName.length).toLowerCase();
        if (extFile=="jpg" || extFile=="jpeg" || extFile=="png"){
            //TO DO
        }else{
            alert("Only jpg/jpeg and png files are allowed!");
        }   
    }
</script>
</body>
</html>

Explanation:

  1. The accept attribute filters the files that will be displayed in the file chooser popup. However, it is not a validation. It is only a hint to the browser. The user can still change the options in the popup.
  2. The javascript only validates for file extension, but cannot really verify if the select file is an actual jpg or png.
  3. So you have to write for file content validation on server side.
2
  • 3
    most complete answer Aug 1, 2018 at 19:24
  • Great, this is what I was looking for. When the alert is shown I clear the input field value like so: document.getElementById("fileName").value = "";
    – stickyuser
    Apr 28, 2023 at 16:27
33

This can be achieved by

<input type="file" accept="image/*" /> 

But this is not a good way. you have to code on the server side to check the file an image or not.

Check if image file is an actual image or fake image

if(isset($_POST["submit"])) {
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
    if($check !== false) {
        echo "File is an image - " . $check["mime"] . ".";
        $uploadOk = 1;
    }
    else {
        echo "File is not an image.";
        $uploadOk = 0;
    }
}

For more reference, see here

http://www.w3schools.com/tags/att_input_accept.asp
http://www.w3schools.com/php/php_file_upload.asp

18

Using type="file" and accept="image/*" (or the format you want), allow the user to chose a file with specific format. But you have to re check it again in client side, because the user can select other type of files. This works for me.

<input #imageInput accept="image/*" (change)="processFile(imageInput)" name="upload-photo" type="file" id="upload-photo" />

And then, in your javascript script

processFile(imageInput) {
    if (imageInput.files[0]) {
      const file: File = imageInput.files[0];
      var pattern = /image-*/;

      if (!file.type.match(pattern)) {
        alert('Invalid format');
        return;
      }

      // here you can do whatever you want with your image. Now you are sure that it is an image
    }
  }
5
  • This is the best answer, as it will check whether the file is actually an image without requiring the developer to specify all the different extensions they want to allow Dec 20, 2019 at 11:45
  • I get your idea. Is this a valid JS syntax: const file: File = imageInput.files[0]; ? Also, assigning id to input is not done in conventional manner.
    – Ivan P.
    Apr 3, 2020 at 5:53
  • In fact, isn't JS, it is typescript. The block code was copied from an Angular project. If you want to use it in a javascript file, you have to omit the type definition (:File) Apr 4, 2020 at 11:52
  • It won't work since the file.type is obtained using the file extension! You need to use a piece of code like this to perform the client side validation: github.com/spine001/client-side-validation-of-file-type Jan 11, 2022 at 17:55
  • Shouldn't the pattern be var pattern = /image\/\w*/;? This checks if there is characters after 'item/'.
    – stomtech
    May 9, 2023 at 17:18
15

Just as an addition: if you want to include all modern image file types with the best cross-browser support it should be:

<input type="file" accept="image/apng, image/avif, image/gif, image/jpeg, image/png, image/svg+xml, image/webp">

This allows all image file types that can be displayed in most browsers while excluding less commons formats like TIFF or formats that are not suitable for the web like PSD.

8

You can add specific type of image or other file type and do validation in your code :

function handleFileInput(e) {
  const [ file ] = e.target.files

  if (!file) return

  const { size, type } = file

  if (size > 2097152) {
    throw "too big"
  } else if (
    type !== "application/pdf" && type !== "application/wps-office.pdf" &&
    type !== "image/jpg" && type !== "image/jpeg" && type !== "image/png"
  ) {
    throw "not the right type"
  } else {
    console.log("file valid")
  }
}
<input type="file" accept="image/x-png,image/jpeg,application/pdf" onchange="handleFileInput(event)" />

6

you can use accept attribute for <input type="file"> read this docs http://www.w3schools.com/tags/att_input_accept.asp

3

In html;

<input type="file" accept="image/*">

This will accept all image formats but no other file like pdf or video.

But if you are using django, in django forms.py;

image_field = forms.ImageField(Here_are_the_parameters)
1
  • 1
    accept="image/*" won't work. It simply filters the browser dialog to show only image files, but there's nothing stopping you from selecting All Files in the drop down and uploading a pdf (or any other file). I think you need to validate it in a way similar to Mati Cassanalli above
    – MattoMK
    Dec 1, 2021 at 19:28
2

If you want to upload multiple images at once you can add multiple attribute to input.

upload multiple files: <input type="file" multiple accept='image/*'>

1

Simple and powerful way(dynamic accept)

place formats in array like "image/*"

var upload=document.getElementById("upload");
var array=["video/mp4","image/png"];
upload.accept=array;
upload.addEventListener("change",()=>{

console.log(upload.value)
})
<input type="file" id="upload" >

1

Other people's answers refactored for ReactJS (hooks)

import React from 'react';

const ImageUploader = () => {

    const handleImageUpload = (e) => {
        // If no file selected, return
        if (e.target.files.length === 0) return false;
        const file = e.target.files[0];

        // If no image selected, return
        if (!/^image\//.test(file.type)) {
            alert(`File ${file.name} is not an image.`);
            return false;
        }

        // ...
    };

    return (
        <>
            <input type='file' accept='image/*' onChange={(e) => handleImageUpload(e)} />
        </>
    );
};

export default ImageUploader;

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