2010-03-21 10 views
5

Chủ đề này đã bị trầy xước một hoặc hai lần, nhưng tôi vẫn còn bối rối. Và Google cũng không thân thiện.Làm thế nào để thiết lập một hệ thống phối hợp Quartz2D của người dùng với tỷ lệ mà tránh được bản vẽ mờ?

Vì Quartz cho phép các hệ tọa độ tùy ý sử dụng biến đổi affine, tôi muốn có thể vẽ những thứ như sơ đồ tầng bằng cách sử dụng tọa độ thực tế, ví dụ: đôi chân. Vì vậy, về cơ bản, vì lợi ích của một ví dụ, tôi muốn mở rộng khung nhìn để khi tôi vẽ một hình chữ nhật 10x10 (ví dụ như hộp 10 inch), tôi nhận được hình chữ nhật 60x60 pixel.

Nó hoạt động, ngoại trừ hình chữ nhật tôi nhận được khá mờ. Một câu hỏi khác ở đây có một câu trả lời giải thích tại sao. Tuy nhiên, tôi không chắc mình hiểu lý do đó, và hơn nữa, tôi không biết cách sửa nó. Đây là mã của tôi:

tôi đặt hệ tọa độ của tôi trong phương pháp xem awakeFromNib tùy chỉnh của tôi:

- (void) awakeFromNib { 
    CGAffineTransform scale = CGAffineTransformMakeScale(6.0, 6.0); 
    self.transform = scale; 
} 

Và đây là thói quen vẽ của tôi:

- (void)drawRect:(CGRect)rect { 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGRect r = CGRectMake(10., 10., 10., 10.); 
    CGFloat lineWidth = 1.0; 
    CGContextStrokeRectWithWidth(context, r, lineWidth); 
} 

Quảng trường tôi nhận được thu nhỏ tốt , nhưng hoàn toàn mờ nhạt. Chơi với lineWidth không hữu ích: khi lineWidth được đặt nhỏ hơn, nó sẽ nhẹ hơn nhưng không sắc nét hơn.

Vậy có cách nào để thiết lập chế độ xem để có hệ tọa độ được chia tỷ lệ để tôi có thể sử dụng tọa độ miền của mình không? Hoặc tôi nên quay trở lại và thực hiện mở rộng quy mô trong thói quen vẽ của tôi?

Lưu ý rằng vấn đề này không xảy ra đối với bản dịch hoặc xoay vòng.

Cảm ơn

Trả lời

2

Tốt, thường xuyên, giải thích vấn đề đưa tôi đến giải pháp.

Sự cố là thuộc tính biến đổi chế độ xem được áp dụng cho nó sau khi nó được đưa vào bộ đệm bit. Biến đổi tỷ lệ phải được áp dụng trước khi vẽ, tức là. trong phương thức drawRect. Vì vậy, xước awakeFromNib Tôi đưa cho, và đây là một drawRect đúng:

- (void)drawRect:(CGRect)rect { 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGAffineTransform scale = CGAffineTransformMakeScale(6.0, 6.0); 
    CGContextConcatCTM(context, scale); 
    CGRect r = CGRectMake(10., 10., 10., 10.); 
    CGFloat lineWidth = 0.1; 
    CGContextStrokeRectWithWidth(context, r, lineWidth); 
} 
+1

Nếu bạn muốn đặt chiều rộng của đường theo điểm bất kể hệ số tỷ lệ, hãy đặt nó thành 'số điểm/hệ số tỷ lệ mong muốn'. Ví dụ: Mặc định là 1 pt/1 × = 1; một dòng 1 pt tại hệ số 6 × của bạn là '1.0/6.0'; một dòng 2 pt sẽ là '2.0/6.0'. –

10

các [vuốt] hình chữ nhật tôi nhận được là khá mờ.

Thông thường, đây là bởi vì bạn vẽ các hình chữ nhật trên toàn bộ số tọa độ và chiều rộng dòng của bạn là 1.

Trong PostScript (và do đó trong hậu duệ của nó: AppKit, PDF, và thạch anh), đơn vị bản vẽ mặc định cho điểm, 1 điểm chính xác là 1/72 inch. Mac và iPhone hiện tại * xử lý mọi điểm như 1 pixel, bất kể độ phân giải thực tế của màn hình, do đó, theo nghĩa thực tế, các điểm (theo mặc định, trên Mac và iPhone) bằng pixel.

Trong PostScript và hậu duệ của nó, các tọa độ không thể tách rời chạy giữa các điểm. 0, 0, ví dụ, là góc dưới bên trái của điểm dưới bên trái. 1, 0 là góc dưới bên phải của cùng một điểm đó (và góc dưới bên trái của điểm tiếp theo ở bên phải).

Đột quỵ được căn giữa trên con đường bạn đang vuốt ve. Như vậy, một nửa sẽ ở bên trong con đường, một nửa bên ngoài.

Trong thế giới (khái niệm) 72 dpi của Mac, hai sự kiện này kết hợp để tạo ra sự cố. Nếu 1 pt bằng 1 pixel, và bạn áp dụng một nét 1 pt giữa hai pixel, thì một nửa cú đánh sẽ chạm vào từng pixel đó.

Quartz, ít nhất, sẽ hiển thị điều này bằng cách tô màu hiện tại thành cả hai pixel ở một nửa alpha của màu. Nó xác định điều này bằng cách bao nhiêu điểm ảnh được bao phủ bởi đột quỵ khái niệm; nếu bạn sử dụng chiều rộng dòng 1,5 pt, một nửa trong số đó là 0,75 pt, bằng 3/4 trong mỗi pixel 1 pt, do đó màu sẽ được hiển thị ở 0,75 alpha. Điều này, tất nhiên, đi đến kết luận tự nhiên: Nếu bạn sử dụng chiều rộng dòng 2 pt, mỗi pixel được che hoàn toàn, vì vậy alpha sẽ là 1. Đó là lý do tại sao bạn có thể thấy hiệu ứng này với nét 1 pt và không phải là Đột quỵ 2 pt.

Có một số cách giải quyết:

  • nửa điểm dịch: Chính xác những gì nó nói trên hộp, bạn dịch lên và phải bằng một nửa điểm, bồi thường cho nói trên 1-pt-cắt-in -phân xưởng.

    Điều này làm việc trong các trường hợp đơn giản, nhưng loại bỏ khi bạn liên quan đến bất kỳ phép biến đổi phối hợp nào khác ngoại trừ bản dịch toàn điểm. Tức là, bạn có thể dịch 30, 20 và nó vẫn hoạt động, nhưng nếu bạn dịch 33 + 1/3, 25.252525 ... hoặc nếu bạn mở rộng hoặc xoay, bản dịch nửa điểm của bạn sẽ vô ích .

  • Đột quỵ bên trong: Clip đầu tiên, sau đó tăng gấp đôi chiều rộng của đường (vì bạn sẽ chỉ vẽ một nửa), sau đó là nét vẽ.

    Điều này có thể yêu cầu phải nhảy tung hứng nếu bạn có nhiều bản vẽ khác để làm, vì bạn không muốn đường cắt đó ảnh hưởng đến bản vẽ khác của bạn.

  • Đột quỵ bên ngoài: Về cơ bản giống như đột quỵ bên trong, ngoại trừ việc bạn đảo ngược đường dẫn trước khi cắt.

    Có thể tốt hơn (ít bị giật gân hơn) so với đột quỵ bên trong nếu bạn chắc chắn rằng đường dẫn bạn muốn đột quỵ sẽ không chồng chéo lên nhau. Mặt khác, nếu bạn cũng muốn điền vào đường dẫn, thì việc tung hứng gstate trở lại.

* Điều này sẽ không kéo dài mãi mãi. Apple đã giảm các gợi ý trong một thời gian rằng họ sẽ thay đổi ít nhất độ phân giải bản vẽ của Mac tại một số điểm. Nền tảng API cho sự thay đổi như vậy là khá nhiều ở đó; đó là tất cả vấn đề của Apple khi ném công tắc.

+0

tất cả là rất đúng, ngoại trừ điều này không phải là nguyên nhân của sự mờ ảo mà tôi đã trải qua. Sự mờ là do thực tế, 'UIView.transform' được áp dụng cho khung nhìn như là một bước sau blitting. Vì vậy, ở đây nó mở rộng bản đồ bit được vẽ bởi 'drawRect'. Đơn giản bằng cách áp dụng biến đổi * ngay từ đầu * của 'drawRect', sửa nó. Điều này làm cho 'UIView.transform' vô ích cho việc mở rộng quy mô. Tất nhiên, tôi vẫn thấy những gì bạn mô tả - điểm ảnh giữa hai bên. Hiển thị trực quan trên nét ảnh dọc và ngang 1 pixel sẽ xuất hiện dưới dạng màu xám thay vì màu đen, thay vì mờ. –