草庐IT

ios - 缩放后在 UIImageView 内的位置查找 RGB 值

coder 2024-01-27 原文

我在 iPad 上有一个 png 图像,尺寸为 1214x1214(视网膜尺寸是它的两倍),并将其设置为位于屏幕坐标 (0,-20) 的 UIImageView。为了在设备旋转/方向更改期间适合屏幕,我将其设置为 Aspect Fit 类型。

我想要做的是能够触摸屏幕并读出触摸下像素的 RGB 值。我已经实现了 UIGestureRecognizer 并将其绑定(bind)到 UIImage,并且成功地获取了触摸坐标。

给我带来麻烦的是,我已经尝试实现几种检索 RGB 值的方法(例如 [如何获取 iphone 上图像上像素的 RGB 值])1 但我的 RGB 值看起来好像图像倾斜并映射到 UIView 上的不同位置。

我的问题是,我如何满足我已将 UIImageView 设置为 Aspect Fit 以及设备可能处于横向或纵向(上下颠倒或垂直向上)的事实?

最佳答案

好的,所以我解决了,这可能对尝试做类似事情的人有帮助。

我使用另一个答案中的这个函数计算了图像的缩放大小

-(CGRect)frameForImage:(UIImage*)image inImageViewAspectFit:(UIImageView*)imageView
{
    float imageRatio = image.size.width / image.size.height;

    float viewRatio = imageView.frame.size.width / imageView.frame.size.height;

    if(imageRatio < viewRatio)
    {
        float scale = imageView.frame.size.height / image.size.height;

        float width = scale * image.size.width;

        float topLeftX = (imageView.frame.size.width - width) * 0.5;

        return CGRectMake(topLeftX, 0, width, imageView.frame.size.height);
    }
    else
    {
        float scale = imageView.frame.size.width / image.size.width;

        float height = scale * image.size.height;

        float topLeftY = (imageView.frame.size.height - height) * 0.5;

        return CGRectMake(0, topLeftY, imageView.frame.size.width, height);
    }
}

通过将函数注册为监听器获取接触点

CGPoint tapPoint = [sender locationInView:imageMap];

根据我的图像因 iPad 旋转而移动到的位置更改了触摸点

if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait ||
   [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown )
  {
  // portrait (y has increased, x has stayed the same)
  tapPoint.y -= rectScaleSize.origin.y;
  }
else  
  {
  // landscape (x has increased, y has stayed the same)
  tapPoint.x -= rectScaleSize.origin.x;
  }

然后根据图像的原始大小及其纵横比大小重新缩放

tapPoint.x = (tapPoint.x * imageMap.image.size.width) / rectScaleSize.size.width;
tapPoint.y = (tapPoint.y * imageMap.image.size.height) / rectScaleSize.size.height;

其中 imageMap.image 是我的原始图像,rectScaleSize 是 frameForImage 函数的返回值

最后得到RGB值

CGImageRef image  = [imageMap.image CGImage];
NSUInteger width  = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
// NSLog(@"RGB Image is %d x %d",width,height);

CGColorSpaceRef colorSpace  = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData      = malloc(height * width * 4);
NSUInteger bytesPerPixel    = 4;
NSUInteger bytesPerRow      = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;

CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height),image);
CGContextRelease(context);

int byteIndex = (bytesPerRow * (int)tapPoint.y) + (int)tapPoint.x * bytesPerPixel;
int red = rawData[byteIndex];
int green = rawData[byteIndex + 1];
int blue = rawData[byteIndex + 2];
//int alpha = rawData[byteIndex + 3];

NSLog(@"RGB is %d,%d,%d",red,green,blue);

看起来效果还不错,希望能派上用场。 如果我做错了什么,欢迎评论!

关于ios - 缩放后在 UIImageView 内的位置查找 RGB 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11014010/

有关ios - 缩放后在 UIImageView 内的位置查找 RGB 值的更多相关文章

  1. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. ruby - Rails 3 的 RGB 颜色选择器 - 2

    状态:我正在构建一个应用程序,其中需要一个可供用户选择颜色的字段,该字段将包含RGB颜色代码字符串。我已经测试了一个看起来很漂亮但效果不佳的。它是“挑剔的颜色”,并托管在此存储库中:https://github.com/Astorsoft/picky-color.在这里我打开一个关于它的一些问题的问题。问题:请建议我在Rails3应用程序中使用一些颜色选择器。 最佳答案 也许页面上的列表jQueryUIDevelopment:ColorPicker为您提供开箱即用的产品。原因是jQuery现在包含在Rails3应用程序中,因此使用基

  6. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  8. ruby - 正则表达式在哪个位置失败? - 2

    我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束

  9. ruby-on-rails - 在 Rails 中更高效地查找或创建多条记录 - 2

    我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr

  10. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

随机推荐