It is currently Tue May 23, 2017 9:53 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Using CGImageCreate to create an image in PureBasic
PostPosted: Sun May 03, 2015 2:04 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 1948
This Objective-C code obtains some raw bitmap information from the given data object, and then creates a CGImage from it, which is then converted to an NSImage:
Code:
CGColorSpaceRef color = CGColorSpaceCreateDeviceGray();

if ([data pixelDataType] == ICScannerPixelDataTypeRGB) color = CGColorSpaceCreateDeviceRGB();

CGDataProviderRef provider = CGDataProviderCreateWithCFData(CFDataCreate(NULL, [[data dataBuffer] bytes], [data dataSize]));

CGImageRef image = CGImageCreate([data fullImageWidth], [data fullImageHeight], [data bitsPerComponent], [data bitsPerPixel],
[data bytesPerRow], color, kCGBitmapByteOrderDefault|kCGImageAlphaNone, provider, NULL, false, kCGRenderingIntentDefault);

NSImage *finImage = [[NSImage alloc] initWithCGImage:image size:NSMakeSize([data fullImageWidth], [data fullImageHeight])];

CGImageRelease(image);
CGDataProviderRelease(provider);
CGColorSpaceRelease(color);

As can be seen from the code, the CGImage is created using the following properties, which looks somewhat similar to Windows' BITMAPINFOHEADER:
- dataSize
- dataBuffer
- bitsPerPixel
- bytesPerRow
- pixelDataType
- fullImageWidth
- fullImageHeight
- bitsPerComponent


There was a similar example by wilbert, in this post, which created a PureBasic-usable image from an NSImage which was created from a CGImage, but in that example, the source image was returned from a screen capture function instead of being created from raw data.

:?: Would it be possible to duplicate the above code in PureBasic, and to create a PureBasic-usable image from the raw data?

:?: Or better still, would it be possible to use the raw data with PureBasic's native image functions to create an image?


Thanks in advance. :D

_________________
Texas Instruments 99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too!


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Sun May 03, 2015 3:46 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 2837
Location: Netherlands
What kind of raw data ?
Is it pixel data or something like tiff encoded ?

_________________
MacOS 10.12, PB 5.51 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Sun May 03, 2015 4:02 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 1948
wilbert wrote:
What kind of raw data ?
Is it pixel data or something like tiff encoded ?
Hi wilbert; thanks for your quick reply. :D

This is related to the scanner code that we were working on in the other thread. The raw image data is returned by the didScanToBandData() method, and presumably it could be the format that was set under the documentUTI property; public.png as you had recommended in that example.

However, since this didScanToBandData() method is only called when scanning in memory transfer mode, it might not comply with the documentUTI property, which is used only in file transfer mode.

Couldn't it just be raw image data to be built upon the given properties? (dataSize, dataBuffer, bitsPerPixel, bytesPerRow, pixelDataType, etc.) :?

_________________
Texas Instruments 99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too!


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Sun May 03, 2015 5:57 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 2837
Location: Netherlands
I think you have two options.
One is to create a CGImage like the code from your first post and draw that onto a PB created image.
The other one is to decode the raw pixel data yourself.
Especially if you always use the same bit depth that shouldn't be overly complicated I think.
How do you select if the scan should be color or b/w and the bit depth (1, 8 or 16) ?

_________________
MacOS 10.12, PB 5.51 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Sun May 03, 2015 7:30 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 1948
wilbert wrote:
One is to create a CGImage like the code from your first post and draw that onto a PB created image.
Hi wilbert. Is it possible to convert that Objective-C CGImageCreate code into PureBasic? The main point would be to obtain and display an image from the given image data object.

wilbert wrote:
The other one is to decode the raw pixel data yourself.
Especially if you always use the same bit depth that shouldn't be overly complicated I think.
How do you select if the scan should be color or b/w and the bit depth (1, 8 or 16) ?
The bit depths (1, 8, 16 bits), and the pixel data types (BW, Gray, RGB, Palette, CMY, CMYK, YUV, YUVK, CIEXYZ), are selectable/obtainable through the scanner unit properties.

Would these be required in order to build the image?

_________________
Texas Instruments 99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too!


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Sun May 03, 2015 8:01 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 2837
Location: Netherlands
TI-994A wrote:
Is it possible to convert that Objective-C CGImageCreate code into PureBasic? The main point would be to obtain and display an image from the given image data object.

Yes, CGImageCreate can be used if you import the function using ImportC.

TI-994A wrote:
Would these be required in order to build the image?

Only if you want to decode the dataBuffer yourself.

_________________
MacOS 10.12, PB 5.51 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Sun May 03, 2015 8:33 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 1948
wilbert wrote:
Yes, CGImageCreate can be used if you import the function using ImportC.
Trying to decode the raw data may be a little overkill for this simple requirement.

When importing these functions, could all the parameters be substituted with integers?
Code:
CFDataCreate(allocator.i, bytes.i, length.i)
CGDataProviderCreateWithCFData(data.i)
CGImageCreate(width.i, height.i, bitsPerComponent.i, bitsPerPixel.i, bytesPerRow.i, colorspace.i, bitmapInfo.i, provider.i, decode.i, shouldInterpolate.i, intent.i)
There seems to be some unique data types, like CGColorSpace!, CGBitmapInfo, CGDataProvider!, UnsafePointer<CGFloat>, and CGColorRenderingIntent. :shock:

_________________
Texas Instruments 99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too!


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Mon May 04, 2015 7:08 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 2837
Location: Netherlands
I can't convert the whole thing since I can't test it (no recognized scanner) but here's something that might help you
Code:
#kCGBitmapByteOrderDefault = 0
#kCGImageAlphaNone = 0
#kCGRenderingIntentDefault = 0

ImportC ""
  CFDataCreate(allocator, *bytes, length)
  CFRelease(cf)
  CGColorSpaceCreateDeviceGray()
  CGColorSpaceCreateDeviceRGB()
  CGColorSpaceRelease(colorspace)
  CGDataProviderCreateWithCFData(cfdata)
  CGDataProviderRelease(provider)
  CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, space, bitmapInfo, provider, *decode, shouldInterpolate, intent)
  CGImageRelease(image)
EndImport



; create raw grayscale data

Dim GrayScaleData.a(99, 99)
RandomSeed(0)
RandomData(@GrayScaleData(), 100 * 100)

; create cgimage

color = CGColorSpaceCreateDeviceGray()

cfdata = CFDataCreate(#Null, @GrayScaleData(), 100 * 100)
provider = CGDataProviderCreateWithCFData(cfdata)

image = CGImageCreate(100, 100, 8, 8, 100, color, #kCGBitmapByteOrderDefault|#kCGImageAlphaNone, provider, #Null, #False, #kCGRenderingIntentDefault)

; create purebasic image

size.NSSize\width = 100
size\height = 100

nsimage = CocoaMessage(0, CocoaMessage(0, 0, "NSImage alloc"), "initWithCGImage:", image, "size:@", @size)
CreateImage(0, 100, 100)
StartDrawing(ImageOutput(0))
DrawImage(nsimage, 0, 0)
CocoaMessage(0, nsimage, "release")
StopDrawing()

; release some things

CGDataProviderRelease(provider)
CFRelease(cfdata)
CGColorSpaceRelease(color)

; show result

If OpenWindow(0, 0, 0, 100, 100, "Image test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ImageGadget(0, 0, 0, 100, 100, ImageID(0))
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

_________________
MacOS 10.12, PB 5.51 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Mon May 04, 2015 5:20 pm 
Offline
Addict
Addict
User avatar

Joined: Sat Feb 19, 2011 3:47 am
Posts: 1948
wilbert wrote:
Code:
color = CGColorSpaceCreateDeviceGray()
cfdata = CFDataCreate(#Null, @GrayScaleData(), 100 * 100)
provider = CGDataProviderCreateWithCFData(cfdata)
image = CGImageCreate(100, 100, 8, 8, 100, color, #kCGBitmapByteOrderDefault|#kCGImageAlphaNone, provider, #Null, #False, #kCGRenderingIntentDefault)
Thanks wilbert! That's precisely what I was looking for. :D

It's funny how all those fancy NS object types can just be substituted with simple integer references. :lol:

_________________
Texas Instruments 99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too!


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Fri Dec 23, 2016 11:07 am 
Offline
Enthusiast
Enthusiast

Joined: Tue Jun 21, 2011 10:39 am
Posts: 326
wilbert wrote:
I can't convert the whole thing since I can't test it (no recognized scanner) but here's something that might help you
Code:
#kCGBitmapByteOrderDefault = 0
#kCGImageAlphaNone = 0
#kCGRenderingIntentDefault = 0

ImportC ""
  CFDataCreate(allocator, *bytes, length)
  CFRelease(cf)
  CGColorSpaceCreateDeviceGray()
  CGColorSpaceCreateDeviceRGB()
  CGColorSpaceRelease(colorspace)
  CGDataProviderCreateWithCFData(cfdata)
  CGDataProviderRelease(provider)
  CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, space, bitmapInfo, provider, *decode, shouldInterpolate, intent)
  CGImageRelease(image)
EndImport



; create raw grayscale data

Dim GrayScaleData.a(99, 99)
RandomSeed(0)
RandomData(@GrayScaleData(), 100 * 100)

; create cgimage

color = CGColorSpaceCreateDeviceGray()

cfdata = CFDataCreate(#Null, @GrayScaleData(), 100 * 100)
provider = CGDataProviderCreateWithCFData(cfdata)

image = CGImageCreate(100, 100, 8, 8, 100, color, #kCGBitmapByteOrderDefault|#kCGImageAlphaNone, provider, #Null, #False, #kCGRenderingIntentDefault)

; create purebasic image

size.NSSize\width = 100
size\height = 100

nsimage = CocoaMessage(0, CocoaMessage(0, 0, "NSImage alloc"), "initWithCGImage:", image, "size:@", @size)
CreateImage(0, 100, 100)
StartDrawing(ImageOutput(0))
DrawImage(nsimage, 0, 0)
CocoaMessage(0, nsimage, "release")
StopDrawing()

; release some things

CGDataProviderRelease(provider)
CFRelease(cfdata)
CGColorSpaceRelease(color)

; show result

If OpenWindow(0, 0, 0, 100, 100, "Image test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ImageGadget(0, 0, 0, 100, 100, ImageID(0))
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Hi wilbert. Do you know why this is not working on newer versions of PB? It works on 5.1 and 5.2 but not on 5.4 and above?

Thanks!


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Fri Dec 23, 2016 11:39 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 2837
Location: Netherlands
coder14 wrote:
Do you know why this is not working on newer versions of PB? It works on 5.1 and 5.2 but not on 5.4 and above?

I don't know why it isn't working.
For some reason drawing the image using the vector library does seem to work.
Code:
nsimage = CocoaMessage(0, CocoaMessage(0, 0, "NSImage alloc"), "initWithCGImage:", image, "size:@", @size)
CreateImage(0, 100, 100)
StartVectorDrawing(ImageVectorOutput(0))
DrawVectorImage(nsimage)
CocoaMessage(0, nsimage, "release")
StopVectorDrawing()

_________________
MacOS 10.12, PB 5.51 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Fri Dec 23, 2016 12:01 pm 
Offline
Enthusiast
Enthusiast

Joined: Tue Jun 21, 2011 10:39 am
Posts: 326
wilbert wrote:
coder14 wrote:
Do you know why this is not working on newer versions of PB? It works on 5.1 and 5.2 but not on 5.4 and above?

I don't know why it isn't working.
For some reason drawing the image using the vector library does seem to work.
Code:
nsimage = CocoaMessage(0, CocoaMessage(0, 0, "NSImage alloc"), "initWithCGImage:", image, "size:@", @size)
CreateImage(0, 100, 100)
StartVectorDrawing(ImageVectorOutput(0))
DrawVectorImage(nsimage)
CocoaMessage(0, nsimage, "release")
StopVectorDrawing()

That works! Thank you wilbert! :D

Getting weary weeding out this stuff. But some of the new stuff is great too! :cry: :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Fri Dec 23, 2016 8:22 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 2837
Location: Netherlands
coder14 wrote:
That works! Thank you wilbert! :D


This alternative might also work
Code:
#kCGBitmapByteOrderDefault = 0
#kCGImageAlphaNone = 0
#kCGRenderingIntentDefault = 0

ImportC ""
  CFDataCreate(allocator, *bytes, length)
  CFRelease(cf)
  CGColorSpaceCreateDeviceGray()
  CGColorSpaceCreateDeviceRGB()
  CGColorSpaceRelease(colorspace)
  CGDataProviderCreateWithCFData(cfdata)
  CGDataProviderRelease(provider)
  CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, space, bitmapInfo, provider, *decode, shouldInterpolate, intent)
  CGImageRelease(image)
EndImport



; create raw grayscale data

Dim GrayScaleData.a(99, 99)
RandomSeed(0)
RandomData(@GrayScaleData(), 100 * 100)

; create cgimage

color = CGColorSpaceCreateDeviceGray()

cfdata = CFDataCreate(#Null, @GrayScaleData(), 100 * 100)
provider = CGDataProviderCreateWithCFData(cfdata)

image = CGImageCreate(100, 100, 8, 8, 100, color, #kCGBitmapByteOrderDefault|#kCGImageAlphaNone, provider, #Null, #False, #kCGRenderingIntentDefault)

; create purebasic image

rect.NSRect\size\width = 100
rect\size\height = 100

nsimage = CocoaMessage(0, CocoaMessage(0, 0, "NSImage alloc"), "initWithCGImage:", image, "size:@", @rect\size)
CreateImage(0, 100, 100)
StartDrawing(ImageOutput(0))
CocoaMessage(0, nsimage, "drawInRect:@", @rect)
CocoaMessage(0, nsimage, "release")
StopDrawing()

; release some things

CGDataProviderRelease(provider)
CFRelease(cfdata)
CGColorSpaceRelease(color)

; show result

If OpenWindow(0, 0, 0, 100, 100, "Image test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ImageGadget(0, 0, 0, 100, 100, ImageID(0))
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf


It uses CocoaMessage(0, nsimage, "drawInRect:@", @rect) to draw the image.

_________________
MacOS 10.12, PB 5.51 x64


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Sat Dec 24, 2016 3:34 am 
Offline
Enthusiast
Enthusiast

Joined: Tue Jun 21, 2011 10:39 am
Posts: 326
wilbert wrote:
It uses CocoaMessage(0, nsimage, "drawInRect:@", @rect) to draw the image.
This does not work on 10.7 but works on 10.11. I get an error that the object does not support drawInRect.

Anyway I am happy that vector drawing works. Any "drawbacks" for using it? :P


Top
 Profile  
Reply with quote  
 Post subject: Re: Using CGImageCreate to create an image in PureBasic
PostPosted: Sat Dec 24, 2016 6:10 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Aug 08, 2004 5:21 am
Posts: 2837
Location: Netherlands
coder14 wrote:
Anyway I am happy that vector drawing works. Any "drawbacks" for using it? :P

Not that I know of. :)

_________________
MacOS 10.12, PB 5.51 x64


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye