- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想知道是否有人可以帮我弄清楚如何确定 UIImage 中的主要原色和次色。我在 Google 中找不到任何非常有用的东西。
最佳答案
基于上面的 Panic 博客,这是一个快速的方法(<10ms 取决于变量)。
获取 UIImage 输入和输出:
将 UIImage 传递给方法时,还要传递一个“边缘”。这是指图像的哪一部分暴露给 View 的其余部分(请参见下图了解详情):
**
第一步。
** 设置维度。这是指图像的横向和向下应该有多少像素。
第 2 步。根据尺寸输入调整图像大小(例如 20 x 20 = 400 像素)。
第 3 步。 创建一个颜色数组,从第 2 步中创建的原始数据中提取 RGB 值。另外收集沿所选边缘运行的像素。
第 4 步。 计算边缘或背景颜色。根据 Panic 博客,这稍后用于对比强调色。
第 5 步。检查收集的颜色(RGB 值)并确定它们是否与边缘/背景颜色充分对比。如果他们不这样做,则所需的最低对比度会降低。此外,对于每个颜色对象,设置它与其他颜色的“距离”。这是对颜色与图像中其他颜色的相似程度的粗略估计。
第 6 步。 按距离对重音进行排序(距离最短意味着最相似),最相似的颜色出现在顶部。将最常出现的颜色设置为主色。
第 7 步。检查剩余的颜色并确定与原色的对比最大的颜色。然后设置你的辅助颜色。
警告:我确信该方法可以改进,但这是一个快速的起点。例如,您可以确定图像右上角或左上角像素的颜色(通常放置后退图标等的位置),并为那里的图标建议对比色。
代码如下:
-(NSDictionary *)coloursForImage:(UIImage *)image forEdge:(int)edge {
NSLog(@"start");
//1. set vars
float dimension = 20;
//2. resize image and grab raw data
//this part pulls the raw data from the image
CGImageRef imageRef = [image CGImage];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char*) calloc(dimension * dimension * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * dimension;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, dimension, dimension, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, dimension, dimension), imageRef);
CGContextRelease(context);
//3. create colour array
NSMutableArray * colours = [NSMutableArray new];
float x = 0, y = 0; //used to set coordinates
float eR = 0, eB = 0, eG = 0; //used for mean edge colour
for (int n = 0; n<(dimension*dimension); n++){
Colour * c = [Colour new]; //create colour
int i = (bytesPerRow * y) + x * bytesPerPixel; //pull index
c.r = rawData[i]; //set red
c.g = rawData[i + 1]; //set green
c.b = rawData[i + 2]; //set blue
[colours addObject:c]; //add colour
//add to edge if true
if ((edge == 0 && y == 0) || //top
(edge == 1 && x == 0) || //left
(edge == 2 && y == dimension-1) || //bottom
(edge == 3 && x == dimension-1)){ //right
eR+=c.r; eG+=c.g; eB+=c.b; //add the colours
}
//update pixel coordinate
x = (x == dimension - 1) ? 0 : x+1;
y = (x == 0) ? y+1 : y;
}
free(rawData);
//4. calculate edge colour
Colour * e = [Colour new];
e.r = eR/dimension;
e.g = eG/dimension;
e.b = eB/dimension;
//5. calculate the frequency of colour
NSMutableArray * accents = [NSMutableArray new]; //holds valid accents
float minContrast = 3.1; //play with this value
while (accents.count < 3) { //minimum number of accents
for (Colour * a in colours){
//NSLog(@"contrast value is %f", [self contrastValueFor:a andB:e]);
//5.1 ignore if it does not contrast with edge
if ([self contrastValueFor:a andB:e] < minContrast){ continue;}
//5.2 set distance (frequency)
for (Colour * b in colours){
a.d += [self colourDistance:a andB:b];
}
//5.3 add colour to accents
[accents addObject:a];
}
minContrast-=0.1f;
}
//6. sort colours by the most common
NSArray * sorted = [[NSArray arrayWithArray:accents] sortedArrayUsingDescriptors:@[[[NSSortDescriptor alloc] initWithKey:@"d" ascending:true]]];
//6.1 set primary colour (most common)
Colour * p = sorted[0];
//7. get most contrasting colour
float high = 0.0f; //the high
int index = 0; //the index
for (int n = 1; n < sorted.count; n++){
Colour * c = sorted[n];
float contrast = [self contrastValueFor:c andB:p];
//float sat = [self saturationValueFor:c andB:p];
if (contrast > high){
high = contrast;
index = n;
}
}
//7.1 set secondary colour (most contrasting)
Colour * s = sorted[index];
NSLog(@"er %i eg %i eb %i", e.r, e.g, e.b);
NSLog(@"pr %i pg %i pb %i", p.r, p.g, p.b);
NSLog(@"sr %i sg %i sb %i", s.r, s.g, s.b);
NSMutableDictionary * result = [NSMutableDictionary new];
[result setValue:[UIColor colorWithRed:e.r/255.0f green:e.g/255.0f blue:e.b/255.0f alpha:1.0f] forKey:@"background"];
[result setValue:[UIColor colorWithRed:p.r/255.0f green:p.g/255.0f blue:p.b/255.0f alpha:1.0f] forKey:@"primary"];
[result setValue:[UIColor colorWithRed:s.r/255.0f green:s.g/255.0f blue:s.b/255.0f alpha:1.0f] forKey:@"secondary"];
NSLog(@"end");
return result;
}
-(float)contrastValueFor:(Colour *)a andB:(Colour *)b {
float aL = 0.2126 * a.r + 0.7152 * a.g + 0.0722 * a.b;
float bL = 0.2126 * b.r + 0.7152 * b.g + 0.0722 * b.b;
return (aL>bL) ? (aL + 0.05) / (bL + 0.05) : (bL + 0.05) / (aL + 0.05);
}
-(float)saturationValueFor:(Colour *)a andB:(Colour *)b {
float min = MIN(a.r, MIN(a.g, a.b)); //grab min
float max = MAX(b.r, MAX(b.g, b.b)); //grab max
return (max - min)/max;
}
-(int)colourDistance:(Colour *)a andB:(Colour *)b {
return abs(a.r-b.r)+abs(a.g-b.g)+abs(a.b-b.b);
}
Color 对象是一个简单的自定义类:
@interface Colour : NSObject
@property int r, g, b, d;
@end
关于ios - 确定 UIImage 的主要颜色和次要颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15962893/
我有一个应用程序,它将在 SQLDatabase 中保存一组图像,然后用户将拍摄一张照片,我希望能够将它与数据库中的图像相匹配。 我不知道从哪里开始,有人可以帮忙吗?指出我正确的方向? 谢谢 最佳答案
在我的项目中,我有两个 UIViewController。在我的第一个 ViewController 上,我有一个 UIImageView,并且有一个来自 url 的图像。在第二个 ViewContr
如何从上下文创建 UIImage 以便我可以返回它?我只希望它有透明像素。我有一种不同的方法,可以将较小的 UIImage 添加到较大的 UIImage,但我需要从头开始。 + (UIImage *)
我想知道如何将 UIImage 居中到 UIButton。我正在使用 UIButton 的 setImage 方法来放置 UIImage .. 最佳答案 您可以使用 contentMode 属性: b
我从相机获取 UIimages 并将它们分配给要显示的 UIImageViews。当我这样做时,相机会给我一个 1200 x 1600 像素的图像,然后我将其分配给我的应用程序中的 UIImageVi
Swift 4 有 Codable这太棒了。但是UIImage默认情况下不符合它。我们怎么能做到这一点? 我试过 singleValueContainer和 unkeyedContainer exte
我的代码在普通设备上运行良好,但在视网膜设备上创建模糊图像。 有人知道我的问题的解决方案吗? + (UIImage *) imageWithView:(UIView *)view { UIGr
我总是得到:CGImageCreate:无效的图像大小:0 x 0。 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; // En
我有一张图片,想创建一张如下所示的黑色图片: 我有一个 View 和一个 ImageView ,因为它是 subview 。 ImageView 的 alpha 为 0.5,其色调颜色为黑色。 Vie
几天来我一直被困在一些必须非常简单的事情上,我已经搜索了几天,但我似乎无法找到正确的代码来工作。 我有两张图片,一张是背景图片,另一张会遮盖第一张图片。我可以用手势移动蒙版图像。我可以缩放、旋转和移动
我正在尝试拍摄类似背景透明的三角形图像,并根据用户偏好在三角形部分或背景部分上应用圆点图像。例如,我如何将圆点应用于三角形部分,然后将条纹应用于图像的透明部分。有针对这种事情的屏蔽技术吗? 非常感谢,
给出下面的图片,百分比为 25%。如何生成另一个代表给定图像径向部分 25% 的 UIImage?非常感谢任何帮助。 输入 输出 - (UIImage *)radialPortion:(float)p
这是我的代码: - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { // at this point the
我正在使用扩展程序对我的图像进行像素化处理,如下所示: func pixellated(scale: Int = 8) -> UIImage? { guard let ciImage = CI
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 6 年前。 Improve t
我有两个 UIImage 实例。我怎样才能创建第三个 UIImage 这只是拼接在一起的两个原始图像?我想要第一张图片在顶部,第二张图片在底部,这样顶部图片的底部边缘与底部图像的顶部边缘齐平。 最佳答
我有一个 UIImage 和一个 CGPoint,它们告诉我应该朝哪个方向移动它以创建另一个图像。背景可以是任何东西。 提供初始 UIImage 我如何创建新的?最有效的方法是什么? 这是我正在做的:
我有一个 UIImage,显示在 UIImageView 中。我在 UIImageView 中还有另一张图片,它位于第一张图片上方。我希望能够仅在第一张图片的边界内拖动第二张图片。为了让我的目标更清楚
我看过这个问题:UIImage Shadow Trouble 但接受的答案对我不起作用。 我想做的是获取一个 UIImage 并向其添加阴影,然后返回一个全新的 UIImage、阴影和所有内容。 这就
我有两张图片:第一张是用户个人图片,第二张是图标(角标(Badge))。 我想在第一个 uiimage(用户图像)的左下角添加第二个 uiimage(图标),并将它们保存到一个新的 Uiimage 中
我是一名优秀的程序员,十分优秀!