如何使用Xcode在Mac OS X上的Obj-C中仅用几行在窗口的画布上绘制/绘制/渲染点或为像素着色? [英] How do I paint/draw/render a dot or color a pixel on the canvas of my window with only a few lines in Obj-C on Mac OS X using Xcode?

查看:219
本文介绍了如何使用Xcode在Mac OS X上的Obj-C中仅用几行在窗口的画布上绘制/绘制/渲染点或为像素着色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从这里的项目的第一阶段开始:

Moving forward from phase 1 of my project here: How do I re-define size/origin of app window in code, overriding nib/xib file parameters, with Obj-C, Xcode 11.3.1 on Mac OS X 10.15.2 (Catalina)?

我当前的目标非常简单(至少抽象地来说):我想在空白的Mac OS X应用程序窗口中(重新)为像素着色.我想经济地做到这一点,用尽可能少的代码行就可以了,因为查看大量代码真是令人讨厌.

My current objective is pretty simple (at least in the abstract): I want to (re-)color a pixel in my blank Mac OS X application window. I want to do this economically, with as few lines of code as humanly possible, because looking at large chunks of code is a real eyesore.

我真的不想处理图像和图像缓冲区,也不想绘制最小的可见线和矩形,但是我愿意尝试所有这些.我最终经历了更多的StackOverflow和Apple Kit文章,这超出了上帝的能力.

I really did not want to deal with images and image buffers or draw the smallest visible lines and rectangles, but I was willing to give all that a try. I ended up going through more StackOverflow and Apple Kit articles than God can count.

最初的议程是:

1)访问我空白的应用程序窗口的内容"

1) access my blank application window’s "content"

2)在该内容中指定我感兴趣的像素

2) specify my pixel of interest within that content

3)使用其色彩空间值访问该像素

3) access that pixel with its colorspace values

4)尽可能直接重写值

4) rewrite the values directly if possible

看起来非常紧凑和简单,对吧?

Seems pretty compact and simple, right?

这就是我的AppDelegate中发生的事情.我用以下方法打开构造函数:

This is what's happening in my AppDelegate. I open the constructing function with:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    /*
     For a more complex app, it's probably better to not put a window into the Main Menu NIB.
     Instead, make a separate NIB for the window.
     Then, load it using a window controller object and ask that for its window.
     */

    NSRect frame = [_window frame];
    frame.origin.x = 0;
    frame.origin.y = 0;
    frame.size.width = 1425;
    frame.size.height = 810;

    [_window setFrame: frame display: YES];

接下来是我尝试绘制某种东西的尝试.

What follows are my attempts at drawing some kind of something.

策略1-NSRectFill:

Tactic #1 - NSRectFill:

NSRect pxl;
    pxl.origin.x = 0;
    pxl.origin.y = 0;
    pxl.size.width = 128;
    pxl.size.height = 128;
    //_window.draw(_ dirtyRect: pxl)
    NSRectFill(pxl);
    //draw(_ dirtyRect: pxl);

策略2(我真的不想尝试这个,因为它让我觉得便宜又懒惰)-NSBezierPath:

Tactic #2 (and I really did not want to try this one as it struck me as cheap and lazy) - NSBezierPath:

NSBezierPath * path = [NSBezierPath bezierPath];
    [path setLineWidth: 4];
    NSPoint startPoint = {  0, 0 };
    NSPoint endPoint   = { 128, 128 };
    [path  moveToPoint: startPoint];
    [path lineToPoint: endPoint];
    [[NSColor redColor] set];
    [path stroke];

我知道我在这里画一条线,但是一点点帮助.

I know I'm drawing a line here, but every little bit helps.

策略3-使用图像和图像表示对象:

Tactic #3 - using image and image rep objects:

NSImage * image;

    //create and define a colorspace object:
    NSColor * rgb = [NSColor colorWithDeviceRed:1.0f
                                green:1.0f
                                 blue:1.0f
                                alpha:1.0f];

    //load the defined colorspace data into image rep:
    NSBitmapImageRep * imgRep = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]];
    [imgRep setColor:rgb atX:128.0 y:128.0];

当然,这一问题是图像对象不包含任何内容.那我要放什么呢?我是否必须在其中加载XIB文件?我已经在网络上看到了一些解决方案,但它们克服了编写尽可能少的行"的观点.

Of course, the problem with this one is that the image object does not hold anything. So what do I put in there? Do I have to load a XIB file in there? I've seen some solutions on the web and they defeat the point of "writing as few lines as possible".

策略4-使用复杂且冗长的函数:

Tactic #4 - using a convoluted and verbose function:

NSColor *MyColorAtScreenCoordinate(CGDirectDisplayID displayID, NSInteger x, NSInteger y)
    { //Function definition is not allowed here
        CGImageRef image = CGDisplayCreateImageForRect(displayID, CGRectMake(x, y, 1, 1));
        NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:image];
        CGImageRelease(image);
        NSColor *color = [bitmap colorAtX:0 y:0];
        [bitmap release];
    }

然后它抱怨: Function definition is not allowed here 因此,我用- (void)将它带到了全球范围,但无论如何它还是抱怨: Expected method body

Then it complains: Function definition is not allowed here So I took this one out to the global scope with - (void) but it complains anyway: Expected method body

策略5-使用bitmapImageRepForCachingDisplayInRect()

Tactic #5 - using bitmapImageRepForCachingDisplayInRect()

NSData *data;
    NSBitmapImageRep *rep;
    rep = [self bitmapImageRepForCachingDisplayInRect:[self frame]];
    [self cacheDisplayInRect:[self frame] toBitmapImageRep:rep];
    data = [rep TIFFRepresentation];

它给了我: No visible @interface for 'AppDelegate' declares the selector 'frame' 我不只是定义同一范围内的框架吗?

It gives me: No visible @interface for 'AppDelegate' declares the selector 'frame' Didn't I just define what frame is within the same scope?

我用以下命令关闭我的委托构造函数:

I close my delegate constructing function with this:

    [_window setFrame: frame display: YES];
}

我尝试过的范围之外

策略6-自定义drawRect():

Tactic #6 - custom drawRect():

- (void)drawRect:(NSRect)dirtyRect {
    // set any NSColor for filling, say white:
    [[NSColor whiteColor] setFill];
    NSRectFill(dirtyRect);
    [super drawRect:dirtyRect];
}

No visible @interface for 'NSObject' declares the selector 'drawRect:'

这是否意味着它不知道自己的drawRect函数?

Does that mean that it doesn't know its own drawRect function?

策略7-从我已经尝试了所有这些方法之一;什么也没画.我在这里做错什么了吗?我的操作顺序有误吗?我试图使所有语法都兼容,并使编译器和构建器可以理解.

I've tried every one of those methods; nothing draws. Am I doing something wrong here? Is my order of operations wrong? I tried to keep it all syntax-compliant and understandable to the compiler and the builder.

旁注1:我真的希望我可以使用尽可能少的类/对象在空白窗口中放置某些内容.

Side note 1: I really wish that I could use as few classes/objects as possible to put something on the blank window.

旁注2:我看过太多的MVC图表和阅读了很多文章,以至于尚不清楚做什么.我已经看到许多代码段是为实现同一目标而进行的尝试,很难相信有不止一种方法可以做一些基本的事情.

Side note 2: I’ve seen so many MVC diagrams and read so many articles that it’s still unclear what does what. I’ve seen so many pieces of code as attempts to achieve the same goal that it’s hard to believe that there is more than one way to do something fundamental.

为窗口的框架内的像素着色的简单行为已成为带有大量过度使用的缓冲区和Xcode无法识别"对象标记的负载冒险.

The simple act of coloring a pixel within the frame of a window has become a loaded adventure marked with over-exploiting buffers and objects Xcode "does not recognize".

No visible @interface declares this selector.

推荐答案

为您的自定义图形创建NSView子类:

Create an NSView subclass for your custom drawing:

@interface MyView : NSView
@end

@implementation MyView

- (void)drawRect:(NSRect)dirtyRect
{
    [[NSColor redColor] setFill];
    NSRectFill(dirtyRect);
}

@end

请确保将其插入到AppDelegate.m的顶层,即外部其他任何@interface@implementation块.

Make sure to insert that at the top-level of your AppDelegate.m - that is, outside any other @interface and @implementation blocks.

创建视图实例并将其分配给窗口的内容视图:

Make an instance of your view and assign it to the content view of your window:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // ... Existing code that sets the window frame

    MyView* myView = [[MyView alloc] initWithFrame:self.window.contentView.bounds];
    self.window.contentView = myView;
}

我在这里做错什么了吗?我的操作顺序有误吗?

Am I doing something wrong here? Is my order of operations wrong?

applicationDidFinishLaunching:是一种委托方法,使您可以响应应用程序生命周期的特定部分.这不是尝试绘制到屏幕上的适当位置.考虑您的应用程序可以有多个窗口,每个窗口包含多个视图或工程图表面.

applicationDidFinishLaunching: is a delegate method allowing you to respond to a specific part of the application lifecycle. It is not the proper place to attempt to draw to the screen. Consider that your application can have multiple windows, each containing multiple views or drawing surfaces.

这是否意味着它不知道自己的drawRect函数?

Does that mean that it doesn't know its own drawRect function?

应用程序委托没有drawRect函数.

The application delegate does not have a drawRect function.

然后它抱怨:这里不允许使用函数定义,所以我用-(void)将其带到了全局范围,但无论如何它还是抱怨:期望的方法体

Then it complains: Function definition is not allowed here So I took this one out to the global scope with - (void) but it complains anyway: Expected method body

一些纯粹是建设性的反馈:似乎特别适合从C或Objective C的初学者入门开始,而不是直接进入编程AppKit.将代码块复制粘贴到applicationDidFinishLaunching:中而不了解它们在做什么,不太可能获得所需的结果.

Some feedback that is intended as purely constructive: it seems like you would do well to start with a beginners introduction to C or Objective C specifically, rather than jumping straight into programming AppKit. Copy-pasting chunks of code into applicationDidFinishLaunching: without understanding what they are doing is unlikely to ever get the results you want.

这篇关于如何使用Xcode在Mac OS X上的Obj-C中仅用几行在窗口的画布上绘制/绘制/渲染点或为像素着色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆