1

I have a string containing bitmap data. Basically, it holds cycles of 1 byte of red, green, blue for each pixel in an image.

I want to manipulate the 8-bit integer value of each color channel in the bitmap. Currently I do this using unpack('C'.strlen($string)) which gives me an array of integers. This is very slow as it converts a lot of data.

Is there a more efficient way to access and modify data from a string as integers?

By more efficient, I mean more efficient than this:

for($i = 0, $l = strlen($string); $i < $l; $i++)
    $string[$i] = chr(floor(ord($string[$i]) / 2));

The manipulation where I divide by 2 is simply an example. The manipulations would be more advanced in a real example.

The problem with the above example is that for say 1 million pixels, you get 3 million function calls initialized from PHP (chr, floor, ord). On my server, this amounts to about 1.4 seconds for an example picture.

1
  • 1
    When someone is asking about more efficient ways to do something, it is absurd to say that it is an opinion based question. Efficiency is easily measurable in terms of raw time measurements. Commented Feb 21, 2014 at 11:59

1 Answer 1

1

PHP strings essentially are byte arrays. The fastest way would simply be:

for ($i = 0, $length = strlen($data); $i < $length; $i++) {
    $byte = $data[$i];

    ...
}

If you manipulate the byte with bitwise operators, you'll hardly get more efficient than that. You can write the byte back into the string with $data[$i] = $newValue. If you need to turn a single byte into an int, use ord(), the other way around use chr().

Sign up to request clarification or add additional context in comments.

7 Comments

This does not work: $byte = $data[$i] * 0.5 and I'll make a test to see if millions of calls to ord() is faster than unpack('C'.strlen($data), $data)
As I said, $byte is a raw byte. Use bitwise operators to work on it. If you want to use integer arithmetic instead, turn it into an integer with ord.
So I should try $data[$i] >> 1 instead? Do you know of sources for doing more fine grained bitwise operations? Like how to multiply by 0.9 using bitwise operations.
Doing any math other than by powers of 2 is going to be tricky using bitwise operators. Again: chr(ord($byte) * 0.5), for example.
ord($byte) >> 1 makes little sense and (int)" " should certainly not be 32 by PHP's casting rules. What exactly are you trying to do? You say you could do it in C, so I'd have assumed you knew the binary operation you're trying to do.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.