使用NSImageView快速显示多个图像 [英] Using NSImageView to display multiple images in quick sucession

查看:262
本文介绍了使用NSImageView快速显示多个图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,在一个窗口中有一个NSImageView.用户应该能够将ANY FILE/FOLDER(不仅是图像)拖放到图像视图中,因此我将NSImageView类子类化以添加对这些类型的支持.

I have an application where, in one window, there is an NSImageView. The user should be able to drag and drop ANY FILE/FOLDER (not only images) into the image view, so I subclassed NSImageView class to add support for those types.

之所以选择NSImageView而不是普通视图,是因为当用户将鼠标悬停在准备放下的文件上时,我还想显示动画(例如,指向下和向上和向下的箭头).我的问题是:这样做的最佳方法(最高效,最快,CPU使用最少等)是什么?

The reason why I chose an NSImageView instead of a normal view is because I also wanted to display an animation (say an arrow pointing downwards and going up and down) when the user hovers over with files ready to drop. My question is this: what would be the best way (most efficient, quickest, least CPU usage, etc) to do this?

事实上,我已经做完了,但是让我问这个问题的事实是,当我将图像设置为以低于0.02秒的速度变化时,它开始滞后.这是我的操作方式:

In fact, I have already done it, but what made me ask this question is the fact that when I set the images to change at a rate below 0.02 sec it starts to lag. Here is how I did it:

在NSImageView子类中:

In the NSImageView subclass:

  • 有一个变量:NSTimer * animTimer;
  • 覆盖awakeFromNib,调用[super awakeFromNib]并使用NSImage将图像加载到数组(约45张图像)中
  • 无论何时用户输入文件,都要以频率= 0.025(小于它并滞后)启动animTimer,并使用选择器设置数组中的下一个图像(称为drawNextImage)
  • 每当用户退出或结束拖放操作时,请调用[animTimer invalidate]停止更新图像

这是我在子类中设置图像的方式:

Here is how I set the image in the subclass:

- (void)drawNextImage
{
    currentImageIndex++; // ivar / kNumberDNDImages is a constant defined as 46
    if (currentImageIndex >= kNumberDNDImages) { currentImageIndex = 0;}
    [super setImage: [imagesArray objectAtIndex: currentImageIndex]]; // imagesArray is ivar
}

那么,我该怎么做才足够快?我希望频率大约为0.01秒,但滞后时间应小于0.025,所以这就是我目前设置的时间.哦,我的图片大小正确(+或-一个像素或其他像素),并且为.png(我需要透明度-例如jpeg不会).

So, how would I do this quick enough? I'd like the frequency to be about 0.01 secs, but less than 0.025 lags, so that is what I have set for the moment. Oh, and my images are the correct size (+ or - one pixel or something) and they are in .png (I need the transparency - jpegs, for example, won't do it).

我尝试遵循NSResponder的建议,并将我的方法更新为:

I have tried to follow NSResponder's suggestion, and have updated my method to this:

- (void)drawNextImage
{
    currentImageIndex++;
    if (currentImageIndex >= kNumberDNDImages) { currentImageIndex = 0;}
    NSRect smallImgRect;
    smallImgRect.origin = NSMakePoint(kSmallImageWidth * currentImageIndex, [self.bigDNDImage size].height); // Up left corner - ??
    smallImgRect.size = NSMakeSize(kSmallImageWidth, [self.bigDNDImage size].height);

    // Bottom left corner - ??
    NSPoint imgPoint = NSMakePoint(([self bounds].size.width - kSmallImageWidth) / 2, 0);

    [bigDNDImage drawAtPoint: imgPoint fromRect: smallImgRect operation: NSCompositeCopy fraction: 1];
}

我还将这个方法和其他拖放方法从NSImageView子类移到了我已经拥有的NSView子类中.除了超类和此方法外,其他所有内容都完全相同.我还修改了一些常量.

I have also moved this method and the other drag and drop methods from the NSImageView subclass to an NSView subclass I already had. Everything is exactly the same, except for the superclass and this method. I also modified some constants.

在对此的早期测试中,我收到了一些错误/警告消息,这些消息不会因NSGraphicsContext之类的原因而停止执行.这些现在已经消失了,但是你知道.我完全不知道它们为什么出现以及它们的含义.如果它们再次出现,我会担心它们,而不是现在:)

In my early testing of this, I got some error/warning messages that didn't stop execution talking abou NSGraphicsContext or something. These have disappeared now, but just so you know. I have absolutely no idea why they were appearing and what they mean. If they ever appear again I'll worry about them, not now :)

这就是我现在正在做的事情:

This is what I'm doing now:

- (void)drawNextImage
{
    currentImageIndex++;
    if (currentImageIndex >= kNumberDNDImages) { currentImageIndex = 0;}
    [self drawCurrentImage];
}
- (void)drawCurrentImage
{
    NSRect smallImgRect;
    smallImgRect.origin = NSMakePoint(kSmallImageWidth * currentImageIndex, 0); // Bottom left, for sure
    smallImgRect.size = NSMakeSize(kSmallImageWidth, [self.bigDNDImage size].height);

    // Bottom left as well
    NSPoint imgPoint = NSMakePoint(([self bounds].size.width - kSmallImageWidth) / 2, 0);

    [bigDNDImage drawAtPoint: imgPoint fromRect: smallImgRect operation: NSCompositeCopy fraction: 1];
}

这里的要点是在调用drawRect时调用drawCurrentImage(请参阅,实际上比我想象的要容易解决).

And the catch here is to call drawCurrentImage when drawRect is called (see, it actually was easier to solve than I thought).

现在,我必须说,我还没有尝试过使用合成图像,因为找不到适合我想要的方式来合并40幅以上图像的好又快的方法(一个接一个).但是对于那些感兴趣的人,我对其进行了修改,使其与NSImageView子类做相同的事情(从数组中读取40多个图像并显示它们),但我发现没有减速带:NSView在0.025以下与NSImageView一样落后.另外,我在使用核心动画时发现了一些问题(图像是在怪异的地方而不是我告诉她的地方绘制的),还有一些关于NSGraphicsContext的警告,我根本不知道如何解决(我是一个完整的对于使用诸如Objective-C的工具进行绘图等方面的新手来说.因此,目前我正在使用NSImageView,除非我找到一种方法来合并所有这些图像并与NSView一起尝试.

Now, I must say I haven't tried this with the composite image, because I couldn't find a good and quick way to merge 40+ images the way I wanted (one next to the other). But for the ones ineterested, I modified this to do the same thing as my NSImageView subclass (reading 40+ images from an array and displaying them) and I found no speed bump: NSView is as laggy below 0.025 as NSImageView. Also I found some problems when using core animation (the image is drawn in weird places instead of the place I tell her to) and some warnings talking about NSGraphicsContext, which I don't know how to solve at all (I'm a complete noob when it comes to drawing and such with Objective-C's tools). So for the time being I'm using NSImageView, unless I find a way to merge all those images and try it with NSView.

推荐答案

我可能会将所有组件图像绘制到一个长图像中,并使用-drawAtPoint:fromRect:operation:fraction:将段绘制到视图中.我敢肯定,借助OpenGL,您可以使其速度更快.

I'd probably draw all of the component images into one long image, and draw segments into a view using -drawAtPoint:fromRect:operation:fraction:. I'm sure you could make it faster than that by resorting to OpenGL, though.

这篇关于使用NSImageView快速显示多个图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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