3
$\begingroup$

I have the following image (8bit, gray scale, 1600*1200 pixels):

enter image description here

What confuses me:

1.

Dimensions[Import[imageFileName, "Byte"]]

gives

{335715}

which cannot be (should be 1600*1200=1920000).

On the other hand:

2.

Dimensions[ImageData[image, "Byte"]]
Dimensions[Flatten@ImageData[image, "Byte"]]

gives:

{1200, 1600}
{1920000}

which is correct.

When I want to calculate the mean brightness of the image I get:

1.

Mean[Import[imageFileName, "Byte"]] // N
124.257

and

2.

Mean@Flatten@ImageData[image, "Byte"]// N
75.6869

What is the difference between method 1. and 2.?

$\endgroup$
9
$\begingroup$

What you are doing in (1) and (2) have nothing to do with each other. The fact that we can use the string "Byte" in both cases happens to be accidental (and I see how that can be confusing). The context, however, is different (Import vs ImageData), and thus the meaning of "Byte" is also completely different.

There are many misunderstandings about how Import works, and people tend to misuse it through guessing what to give as the second argument. Don't guess, instead look up the correct second argument, otherwise there may be surprise results due to the Import trying to be smart and also trying to guess what you mean and guessing wrong.

So how does Import work? Usually,

Import[filename, "format"]

will import the file, assuming that it is in the given format. See the available import formats here. Please look up the "Byte" format to understand what it does: it imports the bytes of the file as numbers. This has nothing to do with the pixels of the image data.

What complicates matters, is that the import framework provides multiple ways to import from the same format (and can import multiple types of data). This is achieved through import elements. Each format has the available elements listed. For example, the "PNG" format has "Data", "Graphics" and "Image" elements (among others), which will give the result as an array, a Graphics expression or an Image. To specify the element, use

Import[filename, {"format", "element"}]

Import usually tries to be smart and can sometimes guess the format. This usually works:

Import[filename]

The format is inferred from the extension. What is confusing is that it is possible to let the format be detected automatically, but specify the element manually. E.g. this often works:

Import[filename, "Data"]

The format is auto-detected, and the "Data" element is imported. But as you see this has the exact same syntax as just specifying the format and using the default element! So it can be ambiguous and confusing. What if we have formats and elements with the same name? (I don't know.)

My advice is to always specify the format, and be aware if the second argument is a format name or an element name. Most importantly, check the documentation and don't randomly guess to avoid accidental ambiguities!

In your case, use

Import["http://i.stack.imgur.com/i6qjE.png", {"PNG", "Data"}]

if you want to get the bytes directly, without having to go through ImageData.

The following also works, but make sure that the PNG format is detected correctly:

Import["http://i.stack.imgur.com/i6qjE.png", "Data"]
$\endgroup$
  • $\begingroup$ Thank you very much for the explanation and your help. $\endgroup$ – mrz Jul 15 '16 at 11:04

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.