2012-06-24 28 views
21

Đây là một bản vẽ đơn giảnDòng UIBezierPath đột quỵ 1px và điền hình chữ nhật có chiều rộng 1px - các kết quả khác nhau.

 

- (void)drawRect:(CGRect)rect 
{ 
    //vertical line with 1 px stroking 
    UIBezierPath *vertLine = [[UIBezierPath alloc] init]; 
    [vertLine moveToPoint:CGPointMake(20.0, 10.0)]; 
    [vertLine addLineToPoint:CGPointMake(20.0, 400.0)]; 
    vertLine.lineWidth = 1.0; 
    [[UIColor blackColor] setStroke]; 
    [vertLine stroke]; 

    //vertical rectangle 1px width 
    UIBezierPath *vertRect= [UIBezierPath bezierPathWithRect:CGRectMake(40.0, 10.0, 1.0, 390.0)]; 
    [[UIColor blackColor] setFill]; 
    [vertRect fill]; 

} 

On phi võng mạc 3GS và mô phỏng dòng đầu tiên là mờ và trông rộng hơn 1 px, nhưng dòng thứ hai là sắc nét.

Thật không may là tôi không có iPhone4 hoặc iPad mới để kiểm tra, nhưng trên giả lập võng mạc cả hai dòng trông giống nhau.

Câu hỏi: Hình chữ nhật thay vì đột quỵ là cách duy nhất để có được kết quả tương tự cho thiết bị không võng mạc và võng mạc?

Trả lời

51

Bạn đang điền vào bên trong hình chữ nhật nhưng bạn đang vuốt đường thẳng từ giữa. Vì tọa độ trong cả hai trường hợp (các góc của hình chữ nhật và tọa độ bắt đầu và kết thúc trong dòng) được định nghĩa là giá trị số nguyên (không có phân số), tọa độ nằm trên ranh giới điểm chính xác.

Tôi đã nói "tọa độ" ở trên khi nói về các điểm của đường kẻ, để không nhầm lẫn chúng với các điểm trên màn hình. Tôi cũng nói "ranh giới điểm" thay vì "ranh giới pixel" cho cùng một lý do. iOS xác định tọa độ của nó và tất cả các điểm trong những gì được gọi là "điểm" thay vì pixel. Một điểm là một phép đo độc lập với độ phân giải. Cả hai thiết bị võng mạc và không võng mạc đều có cùng số điểm trên màn hình, nó chỉ là chúng tương ứng với một số điểm ảnh thực tế khác nhau.

Hãy nhìn vào vuốt ve một đường nằm trên ranh giới điểm (như trong câu hỏi của bạn) so với điền một hình chữ nhật nơi các góc nằm trên ranh giới điểm:

Trong hình minh họa dưới đây, tôi đang vuốt ve một dòng với màu đen và điền vào một hình chữ nhật với màu da cam trên cả màn hình không võng mạc và màn hình võng mạc. Tôi cũng vạch ra đường thẳng và hình chữ nhật có màu xanh lam. Trong cả hai trường hợp, bạn có thể thấy kích thước của một điểm cho độ phân giải đó và so sánh nó với lưới pixel thực tế.

Trong trường hợp không phải võng mạc, bạn có thể thấy rằng cố gắng đột quỵ đường từ trung tâm với đường thẳng 1 điểm (trong trường hợp này tương ứng với chiều rộng đường 1 pixel) sẽ lấp đầy một nửa số pixel trên đầu và một nửa số điểm ảnh dưới đây. Vì pixel chỉ được lấp đầy một nửa, độ mờ cho các pixel đó là 50%. Điều này dẫn đến màu sáng hơn (trên nền trắng). Vì cả hai điểm ảnh trên đầu và bên dưới đều được lấp đầy, nên vuốt toàn bộ các điểm ảnh ở trên và dưới. Điều này làm cho đường trông giống như chiều rộng của nó là 2 pixel thay vì một pixel.

Bạn có thể nhanh chóng so sánh hình ảnh đó với hình chữ nhật được điền ở bên trong.

non retina

Trường hợp tương tự trên một màn hình võng mạc trông khác nhau. Trong trường hợp này, kích thước của một điểm là giống nhau nhưng nó bao gồm 4 pixel thay vì 1. Lần này, khi vuốt dòng, nửa điểm phía trên đường và nửa điểm bên dưới dòng sẽ hoàn toàn lấp đầy hàng pixel trên và dưới vì màn hình có độ phân giải cao hơn. Điều này có nghĩa là dòng có vẻ rộng 1 điểm và màu sắc trông hoàn toàn mờ đục.

Chúng tôi cũng có thể thấy rằng hình chữ nhật được lấp đầy trông giống nhau.

retina


Để sửa lỗi này, bạn sẽ đặt các điểm cho dòng của bạn trên pixel nửa.Việc vuốt đường thẳng từ giữa trên thiết bị có độ phân giải thấp có nghĩa là đường kéo dài nửa điểm trở lên và một nửa điểm xuống dưới. Kể từ khi trung tâm của dòng bây giờ nằm ​​ở trung tâm của điểm, điều này có nghĩa là dòng stroked hoàn toàn nằm trong các điểm ảnh và dòng trông sắc nét. Làm điều này sẽ không có bất kỳ ảnh hưởng nào trên đường võng mạc kể từ khi di chuyển xuống (hoặc lên) một nửa điểm, vẫn có nghĩa là bạn điền đầy đủ các điểm ảnh trên và dưới.

Trong hình minh họa bên dưới (đối với võng mạc) Tôi đã hiển thị cả lưới điểm và lưới pixel.

half pixel non-retina half pixel retina

2

Lý do bạn nhận được kết quả khác nhau với đột quỵ và điền là giải thích của họ về đối số là khác nhau.

Đột quỵ thêm một nửa chiều rộng của đường ở mỗi bên của tọa độ. Vì vậy, điểm của bạn là 20.0 và chiều rộng của dòng là 1px. Kết quả sẽ là một đường màu đen 1 pixel giữa (19,5-20,5), về mặt lý thuyết. Vì không có bất kỳ điểm ảnh không phân giải nào trên màn hình thiết bị, nó sẽ được chuyển đổi giữa 2 pixel màu xám/mờ giữa (19-21). để phá vỡ điều này, bạn cần tổng hợp mỗi tọa độ của bạn bằng 0,5 (như trong CGPointMake (20,5, 10,5)) sao cho chiều rộng sẽ không bị phân chia giữa các pixel nữa.

Tuy nhiên, các đối số trong điền được sử dụng để đặt đường viền của vùng cần điền, CGRectMake (40.0, 10.0, 1.0, 390.0) ngụ ý một vùng giữa (40 - 41). Kết quả là không có phần phân đoạn nào rơi trên các pixel để trông mờ.

Các vấn đề liên quan