I am trying to parse an array of Vectors (from C++'s std::vector) to an NSMutableArray of NSNumber. However, the Vector that I add to the NSNumber array is always nil, even after adding a NSNumber (parsed from std::vector)
In this project, I'm trying to connect the OpenCV Canny Edge Detection Algorithm (C++) to my Swift project. One of their methods returns all the photo's edges as std::vector. So, I'm trying to parse this into an array that is compatible with Swift (using Objective-C++ as the intermediary language). As of right now, it seems that only one line isn't working correctly (as stated above).
I am also a beginner Objective-C++ programmer, so there may be some common errors in the code, which I haven't found.
/*Ptr<LineSegmentDetector>*/
cv::Ptr<cv::LineSegmentDetector> ls = cv::createLineSegmentDetector(cv::LSD_REFINE_STD) ;//Creates the line detector (AKA what I called the edge detector)
std::vector<cv::Vec4f> lines_std;
[image convertToMat: &mat];
// Detect the lines
ls->detect(mat, lines_std);
//Swift compatible NSMutableArray to return from this method
NSMutableArray *edgeLines;
printf("currently finding the edge lines");
for (int i = 0; i < lines_std.size(); i ++) {
NSMutableArray<NSNumber *> *vector;
//Convert from Vec4f to NSNumber
for (int k = 0; k < 4; k ++) {
[vector addObject: [NSNumber numberWithFloat: (lines_std[i][k])]]; //HERE, I'm parsing each float value in each vector (from std::vector<cv::Vec4f>) and adding it to a NSArray, like a vector
}
//Here, I add the vectors to the return NSMutable array
[edgeLines insertObject:vector atIndex:edgeLines.count];
}
return edgeLines;
As stated above, the "vector" variable is always nil, even though I'm adding an NSNumber object to it.
I found the problem, I hadn't used this line:
NSMutableArray *vector = [[NSMutableArray alloc] init];
Related
How can I create an instance of NSValue that contains a CGAffineTransform?
UIKit provides [NSValue valueWithCGAffineTransform:], but AppKit does not.
Do I need to use the valueWithBytes:objCType: static method?
CGAffineTransform is a struct
struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
};
The correct way how to handle structs is mentioned in Key-Value Coding Programming Guide - Representing Non-Object Values (Wrapping and Unwrapping Structures)
CGAffineTransform transform;
NSValue *value = [NSValue valueWithBytes:&transform objCType:#encode(CGAffineTransform)];
I'm doing an animation and want the toValue to get bigger every time i tap an image. My code will work (but doesn't now, of course), but how do you make a toValue an integer?
I have this:
int comboTapAnim = (comboTap / 10) + 1;
then in the animation:
theAnimation.toValue = [comboTapAnim];
Xcode no likey. I have tried other combinations but it must be an NSNumber but I want it to be an int.
I found out the answer!!
[NSNumber numberWithInt:<#(int)#>]
- (void) GetClientRect
NSArray *screenArray = [NSScreen screens];
NSScreen *mainScreen = [NSScreen mainScreen];
unsigned screenCount = [screenArray count];
unsigned index = 0;
for (index; index < screenCount; index++)
{
NSScreen *screen = [screenArray objectAtIndex: index];
NSRect screenRect = [screen visibleFrame];
NSString *mString = ((mainScreen == screen) ? #"Main" : #"not-main");
NSLog(#"Screen #%d (%#) Frame: %#", index, mString, NSStringFromRect(screenRect));
}
}
Above method is use to get frame for mainscreen.
But i want method which return Screen size of NSWindow whose kCGWindowNumber have been passed.
Any idea ?!
Why are you working with a CGWindowID (which is what I assume you meant by kCGWindowNumber)? That's a very unnatural thing to do in most circumstances.
Anyway, you can call CGWindowListCopyWindowInfo(0, theWindowID) and examine the dictionary in the first element of the returned array. Use the key kCGWindowBounds to get a dictionary representation of the bounds rectangle and then CGRectMakeWithDictionaryRepresentation() to convert that to a CGRect.
Are you looking for how to convert the NSWindow -frame, which is in Cocoa's coordinate system, to the Core Graphics coordinate system? The Cocoa coordinate system has its origin at the bottom-left of the primary display, with Y increasing in the up direction. The Core Graphics coordinate system has its origin at the top-left of the primary display, with Y increasing in the down direction.
So, the conversion looks like this:
NSWindow* window = /* ... comes from wherever ... */;
NSRect frame = window.frame;
frame.origin.y = NSMaxY([NSScreen.screens.firstObject frame]) - NSMaxY(frame);
CGRect cgbounds = NSRectToCGRect(frame);
I have a problem with CPTBarPlot in Core Plot on Cocoa.
Namely, I cannot achieve to control step width of bars. X-Axis ticks are set normally as integer from 1 to infinite and drawing Scatter Plot on it works.
However, when bar plot is drawn, only first columns starts (with proper offset, of course) on first tick. Second is a bit further form its tick, so is third and all others as shown on screenshot:
I haven't found any property to control this, however, I found that data source method
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
Behaves differently than when I draw Scatter Plot. namely, it enumerates only integer 3, which is CPTBarPlotBindingBarTips and doesn't enumerate any other constant, I am especially bothered with absence of CPTBarPlotBindingBarLocations.
If I start VerticalBarChart from Plot Gallery mac demo project I've checked and seen that same method enumerates 3,4 and 2 constants in same order.
I am using Core Plot 0.9 namely, I believe the same as in this demo. Still...
How to solve this?
Here is the complete code for labels and ticks on X axis;
x.labelRotation = M_PI/4;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
x.labelOffset = 0.0;
CPTMutableTextStyle *labelStyle = [CPTMutableTextStyle textStyle];
labelStyle.fontSize = 9.0;
x.labelTextStyle = labelStyle;
// NSMutableArray *dateArray = [dataSeries objectAtIndex:0];
NSMutableArray *customTickLocations = [NSMutableArray array];
NSMutableArray *xAxisLabels = [NSMutableArray array];
for (int i=0;i<[dataSeries count];i++) {
[customTickLocations addObject:[NSDecimalNumber numberWithInt:i+1]];
[xAxisLabels addObject:[dataSeries objectAtIndex:i]];
}
// [customTickLocations addObject:[NSDecimalNumber numberWithInt:[dateArray count]]];
NSUInteger labelLocation = 0;
NSMutableArray *customLabels = [NSMutableArray arrayWithCapacity:[xAxisLabels count]];
for (NSNumber *tickLocation in customTickLocations) {
CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText: [xAxisLabels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
newLabel.tickLocation = [tickLocation decimalValue];
newLabel.offset = x.labelOffset + x.majorTickLength;
newLabel.rotation = M_PI/4;
[customLabels addObject:newLabel];
[newLabel release];
}
[x setMajorTickLocations:[NSSet setWithArray:customTickLocations]];
x.axisLabels = [NSSet setWithArray:customLabels];
I have to add that same ticks are being used when scatter plot is drawn on same plot space and it matches perfectly....
The field parameter will be one of the members of this enum:
typedef enum _CPTBarPlotField {
CPTBarPlotFieldBarLocation = 2, ///< Bar location on independent coordinate axis.
CPTBarPlotFieldBarTip = 3, ///< Bar tip value.
CPTBarPlotFieldBarBase = 4 ///< Bar base (used only if barBasesVary is YES).
} CPTBarPlotField;
If the plot's plotRange property is nil (the default), the plot will ask the datasource for locations and tips for each bar. If barBasesVary == YES, it will also ask for base values for each bar.
I am pretty new to Objective C and working with Cocoa Framework. I want to read an image and then extract the image data (just pixel data and not the header) and then write the data to a binary file. I am kind of stuck with this, I was going through the methods of NSImage but I couldn't find a suitable one. Can anyone suggest me some other ways of doing this?
Cocoa-wise, the easiest approach is to use the NSBitmapImageRep class. Once initialized with a NSData object, for example, you can access the color value at any coordinate as a NSColor object using the -setColor:atX:y: and -colorAtX:y: methods. Note that if you call these methods in tight loops, you may suffer a performance hit from objc_msg_send. You could consider accessing the raw bitmap data as C array via the -bitmapData method. When dealing with a RGB image, for example, the color values for each channel are stored at offsets of 3.
For example:
color values: [R,G,B][R,G,B][R,G,B]
indices: [0,1,2, 3,4,5, 6,7,8]
To loop through each pixel in the image and extract the RGB components:
unsigned char *bitmapData = [bitmapRep bitmapData];
if ([bitmapRep samplesPerPixel] == 3) {
for (i = 0; i < [image size].width * [image size].height; i++) {
int base = (i * 3);
// these range from 0-255
unsigned char red = bitmapData[base + 0];
unsigned char green = bitmapData[base + 1];
unsigned char blue = bitmapData[base + 2];
}
}