Get Mime Type from Filename Extension

Get the extension from a MimeType

There are two ways generally:

  • have a mapping of MimeTypes to extensions;
  • compute it, using some logic;

The second approach is really not good, so I offer it only for completion. For the first approach you can use this resource: https://www.freeformatter.com/mime-types-list.html

I would use HashMap<K,V> - the key being the MimeType and the value be the extension (or similar).

File name extension to MIME type

I think you will need to maintain the mappings yourself (you could XHR a physical file and get it, but I doubt you want to do that)...

(function() {

var extToMimes = {
'img': 'image/jpeg',
'png': 'image/png',
...
}

window.getMimeByExt = function(ext) {
if (extToMimes.hasOwnProperty(ext)) {
return extToMimes[ext];
}
return false;
}

})();

jsFiddle.

This will return false if it doesn't exist in your mapping. If you like, you could just return the extToMimes[ext], which will give undefined if it doesn't exist. It also won't accidentally get things up the prototype chain.

There is also the option of accessing it if it is a file input.

var mime = $('input[type="file"]').prop('files')[0].file;

Keep in mind the extension to mime type makes no guarantees about the actual file itself; you'd need to parse it server side to determine what kind of file it really is.

Get Mime type from file extension

you need to use GContentType inside GIO:

https://developer.gnome.org/gio/stable/gio-GContentType.html

and to be precise g_content_type_guess():

https://developer.gnome.org/gio/stable/gio-GContentType.html#g-content-type-guess

which takes either a file name, or the file contents, and returns the guessed content type; from there, you can use g_content_type_get_mime_type() to get the MIME type for the content type.

this is an example for how to use g_content_type_guess():

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gio/gio.h>

int
main (int argc, char *argv[])
{
const char *file_name = "test.html";
gboolean is_certain = FALSE;

char *content_type = g_content_type_guess (file_name, NULL, 0, &is_certain);

if (content_type != NULL)
{
char *mime_type = g_content_type_get_mime_type (content_type);

g_print ("Content type for file '%s': %s (certain: %s)\n"
"MIME type for content type: %s\n",
file_name,
content_type,
is_certain ? "yes" : "no",
mime_type);

g_free (mime_type);
}

g_free (content_type);

return EXIT_SUCCESS;
}

once compiled, the output on Linux is:

Content type for file 'test.html': text/html (certain: no)
MIME type for content type: text/html

explanation: on Linux, content type is a MIME type; this is not true on other platforms, that's why you must convert GContentType strings to MIME type.

also, as you can see, just using the extension will set the boolean is certain flag, as an extension by itself is not enough to determine the accurate content type.

How to check file MIME type with JavaScript before upload?

You can easily determine the file MIME type with JavaScript's FileReader before uploading it to a server. I agree that we should prefer server-side checking over client-side, but client-side checking is still possible. I'll show you how and provide a working demo at the bottom.


Check that your browser supports both File and Blob. All major ones should.

if (window.FileReader && window.Blob) {
// All the File APIs are supported.
} else {
// File and Blob are not supported
}

Step 1:

You can retrieve the File information from an <input> element like this (ref):

<input type="file" id="your-files" multiple>
<script>
var control = document.getElementById("your-files");
control.addEventListener("change", function(event) {
// When the control has changed, there are new files
var files = control.files,
for (var i = 0; i < files.length; i++) {
console.log("Filename: " + files[i].name);
console.log("Type: " + files[i].type);
console.log("Size: " + files[i].size + " bytes");
}
}, false);
</script>

Here is a drag-and-drop version of the above (ref):

<div id="your-files"></div>
<script>
var target = document.getElementById("your-files");
target.addEventListener("dragover", function(event) {
event.preventDefault();
}, false);

target.addEventListener("drop", function(event) {
// Cancel default actions
event.preventDefault();
var files = event.dataTransfer.files,
for (var i = 0; i < files.length; i++) {
console.log("Filename: " + files[i].name);
console.log("Type: " + files[i].type);
console.log("Size: " + files[i].size + " bytes");
}
}, false);
</script>

Step 2:

We can now inspect the files and tease out headers and MIME types.

✘ Quick method

You can naïvely ask Blob for the MIME type of whatever file it represents using this pattern:

var blob = files[i]; // See step 1 above
console.log(blob.type);

For images, MIME types come back like the following:

image/jpeg

image/png

...

Caveat: The MIME type is detected from the file extension and can be fooled or spoofed. One can rename a .jpg to a .png and the MIME type will be be reported as image/png.


✓ Proper header-inspecting method

To get the bonafide MIME type of a client-side file we can go a step further and inspect the first few bytes of the given file to compare against so-called magic numbers. Be warned that it's not entirely straightforward because, for instance, JPEG has a few "magic numbers". This is because the format has evolved since 1991. You might get away with checking only the first two bytes, but I prefer checking at least 4 bytes to reduce false positives.

Example file signatures of JPEG (first 4 bytes):

FF D8 FF E0 (SOI + ADD0)

FF D8 FF E1 (SOI + ADD1)

FF D8 FF E2 (SOI + ADD2)

Here is the essential code to retrieve the file header:

var blob = files[i]; // See step 1 above
var fileReader = new FileReader();
fileReader.onloadend = function(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var header = "";
for(var i = 0; i < arr.length; i++) {
header += arr[i].toString(16);
}
console.log(header);

// Check the file signature against known types

};
fileReader.readAsArrayBuffer(blob);

You can then determine the real MIME type like so (more file signatures here and here):

switch (header) {
case "89504e47":
type = "image/png";
break;
case "47494638":
type = "image/gif";
break;
case "ffd8ffe0":
case "ffd8ffe1":
case "ffd8ffe2":
case "ffd8ffe3":
case "ffd8ffe8":
type = "image/jpeg";
break;
default:
type = "unknown"; // Or you can use the blob.type as fallback
break;
}

Accept or reject file uploads as you like based on the MIME types expected.


Demo

Here is a working demo for local files and remote files (I had to bypass CORS just for this demo). Open the snippet, run it, and you should see three remote images of different types displayed. At the top you can select a local image or data file, and the file signature and/or MIME type will be displayed.

Notice that even if an image is renamed, its true MIME type can be determined. See below.

Screenshot

Expected output of demo






// Return the first few bytes of the file as a hex string

function getBLOBFileHeader(url, blob, callback) {

var fileReader = new FileReader();

fileReader.onloadend = function(e) {

var arr = (new Uint8Array(e.target.result)).subarray(0, 4);

var header = "";

for (var i = 0; i < arr.length; i++) {

header += arr[i].toString(16);

}

callback(url, header);

};

fileReader.readAsArrayBuffer(blob);

}


function getRemoteFileHeader(url, callback) {

var xhr = new XMLHttpRequest();

// Bypass CORS for this demo - naughty, Drakes

xhr.open('GET', '//cors-anywhere.herokuapp.com/' + url);

xhr.responseType = "blob";

xhr.onload = function() {

callback(url, xhr.response);

};

xhr.onerror = function() {

alert('A network error occurred!');

};

xhr.send();

}


function headerCallback(url, headerString) {

printHeaderInfo(url, headerString);

}


function remoteCallback(url, blob) {

printImage(blob);

getBLOBFileHeader(url, blob, headerCallback);

}


function printImage(blob) {

// Add this image to the document body for proof of GET success

var fr = new FileReader();

fr.onloadend = function() {

$("hr").after($("<img>").attr("src", fr.result))

.after($("<div>").text("Blob MIME type: " + blob.type));

};

fr.readAsDataURL(blob);

}


// Add more from http://en.wikipedia.org/wiki/List_of_file_signatures

function mimeType(headerString) {

switch (headerString) {

case "89504e47":

type = "image/png";

break;

case "47494638":

type = "image/gif";

break;

case "ffd8ffe0":

case "ffd8ffe1":

case "ffd8ffe2":

type = "image/jpeg";

break;

default:

type = "unknown";

break;

}

return type;

}


function printHeaderInfo(url, headerString) {

$("hr").after($("<div>").text("Real MIME type: " + mimeType(headerString)))

.after($("<div>").text("File header: 0x" + headerString))

.after($("<div>").text(url));

}


/* Demo driver code */


var imageURLsArray = ["http://media2.giphy.com/media/8KrhxtEsrdhD2/giphy.gif", "http://upload.wikimedia.org/wikipedia/commons/e/e9/Felis_silvestris_silvestris_small_gradual_decrease_of_quality.png", "http://static.giantbomb.com/uploads/scale_small/0/316/520157-apple_logo_dec07.jpg"];


// Check for FileReader support

if (window.FileReader && window.Blob) {

// Load all the remote images from the urls array

for (var i = 0; i < imageURLsArray.length; i++) {

getRemoteFileHeader(imageURLsArray[i], remoteCallback);

}


/* Handle local files */

$("input").on('change', function(event) {

var file = event.target.files[0];

if (file.size >= 2 * 1024 * 1024) {

alert("File size must be at most 2MB");

return;

}

remoteCallback(escape(file.name), file);

});


} else {

// File and Blob are not supported

$("hr").after( $("<div>").text("It seems your browser doesn't support FileReader") );

} /* Drakes, 2015 */
img {

max-height: 200px

}

div {

height: 26px;

font: Arial;

font-size: 12pt

}

form {

height: 40px;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

<form>

<input type="file" />

<div>Choose an image to see its file signature.</div>

</form>

<hr/>

How to determine MIME type of file in android?

First and foremost, you should consider calling MimeTypeMap#getMimeTypeFromExtension(), like this:

// url = file path or whatever suitable URL you want.
public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
return type;
}


Related Topics



Leave a reply



Submit