Re: Optimized pixel manipulation
Re: Optimized pixel manipulation
- Subject: Re: Optimized pixel manipulation
- From: "Ken Ferry" <email@hidden>
- Date: Wed, 8 Oct 2008 20:13:48 -0700
A CGImage is an immutable object. While it is possible in some cases
to physically change the bytes that back it, it does not reliably
work. CG may produce color matched caches or upload data to a
graphics card or what have you. If the data is modified behind the
framework's back, none of those dependent stores are updated. Even if
data modification seems to work in one version of the OS, the timing
internal functions may change in another, and it may no longer work as
desired.
Moreover, directly accessing the pixels of an image tends to be error
prone. Images come in many different formats. For example, you might
get a CMYKA image, or a 1555 RGB with 16 bit little endian data
stream, or a 16 bit per channel non-premultiplied floating point
image. The upshot is that when directly accessing the data backing an
image, there is a tendency to (often accidentally) hardwire
assumptions about bitmap format that don't necessarily hold between
updates of the operating system. Plus, bitmap formats can be added in
the future.
Here are some ways out:
(1) Prefer to draw rather than access pixel data. Many operations can
be accomplished with blend modes and such. The system is designed
with drawing as the priority.
(2) CoreImage is a framework intended for pixel processing. It's very
nice! Rather than directly access data, you provide a kernel that
does local processing of pixels. The framework manages applying your
kernel to the data of the image. A caveat is that there is some
upfront cost associated with its use at all, so for small images,
CG-based techniques (i.e. drawing + blending tricks and such) are
likely to perform better if they apply at all.
(3) If disregarding the above and playing with pixels anyway, make
sure you control the format of the bytes. This can be done by drawing
the image into a bitmap data you allocate yourself, and whose format
you specify at creation. What you can do is keep a single bitmap
context, and each time you need to edit and redraw, call
CGBitmapContextCreateImage to get a CGImage to draw. I believe this
is basically copy on write, so if the CGImage ends up used and
discarded before you modify your context data again, you avoid
anything other than VRAM table manipulation.
OpenGLES may also be an option. I'm not familiar with it, unfortunately.
This all basically applies to NSBitmapImageRep too, by the way. It is
supported to ask for a bitmapImageRep's bitmapData and mutate it, but
behind the scenes that means data copying. And once the bitmap has
drawn again, further modifications to the data will not reliably have
any effect. (See 10.4 AppKit release notes.)
Hope that helps,
Ken Ferry
Cocoa Frameworks
On Wed, Oct 8, 2008 at 10:00 AM, Jean-Daniel Dupas
<email@hidden> wrote:
> How do you create your bitmap context ?
> AFAK, to create a bitmap context, you should use CGBitmapContextCreate()
> that take as first argument the image backing store.
> So you already have it.
> The other way I know, is the create an NSBitmapImageRep, and then using it
> to create an NSGraphicsContext. NSBitmapImageRep as a bitmapData method that
> returns it's buffer.
>
>
> Le 8 oct. 08 à 18:26, Christian Giordano a écrit :
>
>>> If you've created a bitmap context, then you should already own the
>>> backing
>>> bitmap data buffer. You can just manipulate it directly without making a
>>> copy (via a CGImage).
>>
>> How could I access its buffer?
>>
>> Cheers, chr
>>
>> On Wed, Oct 8, 2008 at 5:21 PM, Ken Thomases <email@hidden> wrote:
>>>
>>> On Oct 8, 2008, at 11:02 AM, Christian Giordano wrote:
>>>
>>>> After drawing the shapes, I do pixel operations, of course.
>>>
>>> Are these pixel operations not something which can be accomplished by
>>> changing the way you draw, for example using compositing modes?
>>> Alternatively, do you have access to Core Image and does it do what you
>>> need? Another thing to look at might be vImage.
>>>
>>>> For this
>>>> reason I create a bitmap context and after the drawing I get the
>>>> CGImageRef generated, I copy the pixels, I modify the pixels and then
>>>> I create a new image
>>>
>>
>>>
>>> Cheers,
>>> Ken
>>>
>>>
>> _______________________________________________
>>
>> Cocoa-dev mailing list (email@hidden)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>>
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden