I am using OpenCV in a iPhone project. In this application, I receive a 3x3 matrix from the Opencv function an need to transform it into a NSString. For example:
cv::Mat myMatrix = opencvClass.getMatrix();
NSString *matrixString = myMatrix.toNSString(); // this function does not exist actually but it is what I need
Any suggestions?
Cheers,
I guess you could convert it to a std::stringstream, extract the C array of bytes from it and use this to contruct your NSString :
NSString NSStringFromCvMat(cv::Mat mat)
{
std::stringstream ss;
ss << mat;
return [NSString stringWithCString:ss.str().c_str() encoding:NSASCIIStringEncoding];
}
Untested but should work. The encoding could be a problem. Maybe try different values.
I don't think it is the best solution though, and you could find a beter and cleaner one by diving into OpenCV source code.
Related
I have converted an NSArray to NSString using below code
Suppose i have an array with some data in it.
NSString *sample=[array description];
NSLog(#"%#",sample);
which prints:
(
{
URL = "1a516af1a1c6020260a876231955e576202bbe03.jpg##37911944cc1ea8fd132ee9421a7b3af326afcc19.jpg";
userId = 0;
wallpaperId = 31;
},
{
URL = "a9356863fa43bc3439487198283321622f88e31f.jpg##f09c743ebdc26bb9f98655310a0529b65a472428.jpg";
userId = 0;
wallpaperId = 30;
}
)
It looks like array but it is actually a string.
Now I am wondering, how can I reconvert back to NSArray?
Help appreciated.
And please this not a duplicate question, I couldn't found the same anywhere on SO.
You cannot rely on the results of description as it is not a convert to string operator, but merely a debugging aid. There is nothing to stop it changing between O/S releases and there is no equivalent fromDescription method.
The conventional way of serializing an Objective-C collection to and from a string is to use JSON, so look at the NSJSONSerialization class.
the
NSString componentsseparatedbystring
method will return an array of components separated by a string
In a Cocoa App I would like to display a 2d array of floats in an NSImageView. To make the code as simple as possible, start off by converting the data from float to NSData:
// dataArray: an Nx by Ny array of floats
NSMutableData *nsdata = [NSMutableData dataWithCapacity:0];
long numPixels = Nx*Ny;
for (int i = 0; i < numPixels; i++) {
[nsdata appendBytes:&dataArray[i] length:sizeof(float)];
}
and now try to display the data (the display is left blank):
[theNSImageView setImage:[[NSImage alloc] initWithData:nsdata]];
Is this the correct approach? Is a CGContext needed first? I was hoping to accomplish this with NSData.
I have noted the earlier Stack posts: 32 bit data, close but in reverse, almost worked but no NSData, color image data here, but not much luck getting variations on these working. Thanks for any suggestions.
You can use an NSBitmapImageRep to build up an NSImage float-by-float.
Interestingly, one of its initialisers has the longest method name in all of Cocoa:
- (id)initWithBitmapDataPlanes:(unsigned char **)planes
pixelsWide:(NSInteger)width
pixelsHigh:(NSInteger)height
bitsPerSample:(NSInteger)bps
samplesPerPixel:(NSInteger)spp
hasAlpha:(BOOL)alpha
isPlanar:(BOOL)isPlanar
colorSpaceName:(NSString *)colorSpaceName
bitmapFormat:(NSBitmapFormat)bitmapFormat
bytesPerRow:(NSInteger)rowBytes
bitsPerPixel:(NSInteger)
It's well documented at least. Once you've built it up by supplying float arrays in planes you can then get the NSImage to put in your view:
NSImage *image = [[NSImage alloc] initWithCGImage:[bitmapImageRep CGImage] size:NSMakeSize(width,height)];
Or, slightly cleaner
NSImage *image = [[[NSImage alloc] init] autorelease];
[im addRepresentation:bitmapImageRep];
There is an initialiser which just uses an NSData container:
+ (id)imageRepWithData:(NSData *)bitmapData
although that depends on your bitmapData containing one of the correct bitmap formats.
Ok got it to work. I had tried the NSBitmapImageRep before (thanks Tim) but the part I was missing was in properly converting my floating point data to a byte array. NSData doesn't do that and returns nil. So the solution was not so much in needing to build up an NSImage float-by-float. In fact, one can similarly build up a bitmapContext (using CGBitmapContextCreate (mentioned by HotLicks above)) and that works too, once the floating point data has been represented properly.
I honestly did a) search using key words and b) read the 'questions with similar titles' before asking this.
Also I tried to make this question more concise, but I had a hard time doing that in this case. If you feel the question is too wordy, I get it. Just don't try to answer.
I'm trying to write very simple objective-C programs that mirror the basic assignments in my introductory java class. I worked through an objective-c book over the summer and now I want to do lots of practice problems in objective-c, at the same time as I do java practice problems. I'm avoiding the objective-c GUI environment and just want to focus on working with the language for awhile. I still have a lot to learn about how to figure things out.
The program I'm duplicating from my java homework, is a standard type. I ask the user for number input and string input via the console. I was able to get numeric input from the console using an example I found here using scan f. (I will put the couple code lines below). But I'm unsure on how to get console input and store it in a string (NSString). I'm trying to learn to use the apple documentation and found a reference to a scan type command, but I cannot figure out how to USE the command. The one that seems likely is
scanCharactersFromSet:(NSCharacterSet )scanSet intoString:(NSString *)name;
Here's what I understand and works
int age = 0;
NSLog (#"How old are y'all?");
scanf("%d", &age);
NSLog (#"\n Wow, you are %d !", age);
But I don't understand how to pickup an NSString called 'name'. I THINK I'm supposed to make my 'name'a pointer, because the class is NSString.
(BTW I did try using scanf to pickup the string, but the compiler doesn't like me trying to use scanf in conjunction with name. It says that I shouldn't be using 'scanf' because it's expecting a different kind of data. I'm not sure where I found the data type 'i'. I was looking through my text for different ideas. I'm guessing that scanf is related to 'scanfloat' which clearly deals with numeric data, so this is not a big surprise)
I realize that 'scanf' isn't the right command (and I don't really get why I can't even find scanf in the apple documentation - maybe it's C?)
I'm guessing that scanCharactersFromSet might be the right thing to use, but I just don't understand how you figure out what goes where in the command. I guess I tend to learn by example, and I haven't found an example. I'd like to figure out how to learn properly by reading the documentation. But I'm not there yet.
NSString* name ;
scanf("%i", &name);
//scanCharactersFromSet:(NSCharacterSet *)scanSet intoString:(NSString **)name;
...
My book is oriented towards moving me into a gui environment, so it doesn't deal with input.
Thank you for any pointers you can give me.
Laurel
I would recommend ramping up on C. Objective-c is a thin layer over C and that knowledge will pay for itself over and over.
There's multiple ways in C to read:
http://www.ehow.com/how_2086237_read-string-c.html
For example:
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
char str[50] = {0}; // init all to 0
printf("Enter you Last name: ");
scanf("%s", str); // read and format into the str buffer
printf("Your name is %s\n", str); // print buffer
// you can create an NS foundation NSString object from the str buffer
NSString *lastName = [NSString stringWithUTF8String:str];
// %# calls description o object - in NSString case, prints the string
NSLog(#"lastName=%#", lastName);
[pool drain];
return 0;
NOTE: the simple scanf is succeptible to buffer overruns. There's multiple approaches around this. see:
How to prevent scanf causing a buffer overflow in C?
Here is what Objective C looks like:
NSString *FNgetInput() {
#autoreleasepool {
return [[[NSString alloc] initWithData:[[NSFileHandle fileHandleWithStandardInput] availableData] encoding:NSUTF8StringEncoding] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
}
}
The way to get data from the standard input (or any other file handle) in cocoa is to use the NSFileHandle class. Check the docs for +fileHandleWithStandardInput
Here's how to get user input using Objective-C in 2020:
main.m
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
char str[50] = {0}; // init all to 0
printf("Enter you Last name: ");
scanf("%s", str); // read and format into the str buffer
printf("Your name is %s\n", str); // print buffer
// you can create an NS foundation NSString object from the str buffer
NSString *lastName = [NSString stringWithUTF8String:str];
// %# calls description o object - in NSString case, prints the string
NSLog(#"lastName=%#", lastName);
return 0;
}
return 0;
}
Compile and run:
$ clang -framework Foundation main.m -o app
I'm writing a Cocoa application in Objective-C, and I would like to be able to incorporate Markdown. The user will enter text in Markdown syntax, click an "export" button, and the program will output a file of XHTML.
It seems like there are a lot of options, though. I could use one of the C/C++ implementations, I could run the Perl script as a resource to my Cocoa app, I assume could use the Python implementation and the PyObjC bridge or the Perl implementation and the CamelBones or PerlObjC bridges. What would be the simplest and easiest solution? I'm not doing anything complicated like a real-time rendered preview that would require threading.
I had a look at the various options, and in the end found libsoldout, a very small C implementation that's quite easy to integrate. You just need to include array.[ch], buffer.[ch], markdown.[ch], and renderers.[ch] in your Xcode project, then you can convert an NSString from markdown to HTML like so:
NSString *rawMarkdown;
const char * prose = [rawMarkdown UTF8String];
struct buf *ib, *ob;
int length = rawMarkdown.length + 1;
ib = bufnew(length);
bufgrow(ib, length);
memcpy(ib->data, prose, length);
ib->size = length;
ob = bufnew(64);
markdown(ob, ib, &mkd_xhtml);
NSString *shinyNewHTML = [NSString stringWithUTF8String: ob->data];
NSLog(#"%#", shinyNewHTML);
bufrelease(ib);
bufrelease(ob);
I just used the Sundown implementation which includes SmartyPants support, in an iPad app with great success. Took about 15 minutes to build a test app.
Assume you have a UITextView *textView (which you setDelegate:self) and also a UIWebView *webView in which to display the results:
- (void) textViewDidEndEditing:(UITextView *)textView
{
NSString *rawMarkdown = [textView text];
const char * prose = [rawMarkdown UTF8String];
struct buf *ib, *ob;
int length = [rawMarkdown lengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
ib = bufnew(length);
bufgrow(ib, length);
memcpy(ib->data, prose, length);
ib->size = length;
ob = bufnew(64);
struct sd_callbacks callbacks;
struct html_renderopt options;
struct sd_markdown *markdown;
sdhtml_renderer(&callbacks, &options, 0);
markdown = sd_markdown_new(0, 16, &callbacks, &options);
sd_markdown_render(ob, ib->data, ib->size, markdown);
sd_markdown_free(markdown);
NSString *shinyNewHTML = [NSString stringWithUTF8String: ob->data];
[webView loadHTMLString:shinyNewHTML baseURL:[[NSURL alloc] initWithString:#""]];
bufrelease(ib);
bufrelease(ob);
}
You may want to check out the open-source app Macdown which I wrote (or alternatively rentzsch's Markdownlive), which incorporate this functionality as the sole purpose of the two apps.
I found problems with processing large amounts of markdown with these C-based libraries.
There's a very simple Obj-C library that worked for me here:
https://github.com/mdiep/MMMarkdown
Steps to use MMMarkdown:
Build the OS X or iOS target
Copy include/MMMarkdown.h and either
lib/libMMMarkdown-Mac.a or lib/libMMMarkdown-iOS.a into your project
Then the code is:
#import "MMMarkdown.h"
NSError *error;
NSString *markdown = #"# Example\nWhat a library!";
NSString *htmlString = [MMMarkdown HTMLStringWithMarkdown:markdown error:&error];
// Returns #"<h1>Example</h1>\n<p>What a library!</p>"
I've used peg-markdown, it's much faster than the original perl and can handle a few syntax extensions if you enable them.
Oliver Letterer's GHMarkdownParser translate markdown to HTML.
Phil Toland's QLMarkdown QuickLook generator for markdown files.
I have been able to find methods like -[NSString stringWithCString:encoding:] but they do not seem to play well when the cstring is a pointer.
First up, don't use initWithCString, it has been deprecated.
Couple of ways you can do this:
const *char cString = "Hello";
NSString *myNSString = [NSString stringWithUTF8String:cString];
If you need another encoding like ASCII:
const *char cString = "Hello";
NSString *myNSString = [NSString stringWithCString:cString encoding:NSASCIIStringEncoding];
If you want to see all the string encodings available, in Xcode, hold command + option then double click on NSASCIIStringEncoding in the above code block.
You will be able to see where Apple have declared their enumeration for the string encoding types. Bit quicker than trying to find it in the documentation.
Some other ones you might need:
NSASCIIStringEncoding
NSUnicodeStringEncoding // same as NSUTF16StringEncoding
NSUTF32StringEncoding
Checkout Apple's NSString Class Reference (encodings are at the bottom of the page)
With modern Objective-C (since Xcode 5 at least) you can just do:
char const* cString = "Hello";
NSString *myNSString = #(cString);
stringWithCString:encoding: creates an NSString from a given C string. To create a C string from an NSString, use either the UTF8String method (generally preferred) or cStringUsingEncoding: (if you need an encoding other than UTF-8).