2016-03-21 25 views
3

ben çizmek için kod şu var benim border2.bmp yönü 4'teGraphics.DrawImage() klipleri görüntü

private void Form1_Paint(object sender, PaintEventArgs e) 
{ 
    Bitmap border = new Bitmap("border2.bmp"); 
    int borderThick = border.Height; 

    Graphics g = e.Graphics; 
    Size region = g.VisibleClipBounds.Size.ToSize(); 

    Rectangle desRectW = new Rectangle(0, 0, region.Width - borderThick, borderThick); 

    // 1. LEFT - RIGHT border 
    g.TranslateTransform(30, 30); 
    g.DrawImage(border, desRectW, desRectW, GraphicsUnit.Pixel); 

    // 2. UP - BUTTOM border 
    g.ResetTransform(); 
    g.TranslateTransform(50, 50); 
    g.RotateTransform(90); 
    g.DrawImage(border, desRectW, desRectW, GraphicsUnit.Pixel); 

    // 3. RIGHT-LEFT border 
    g.ResetTransform(); 
    g.TranslateTransform(100, 100); 
    g.RotateTransform(180); 
    g.DrawImage(border, desRectW, desRectW, GraphicsUnit.Pixel); 

    // 4. BOTTOM - UP border 
    g.ResetTransform(); 
    g.TranslateTransform(150, 150); 
    g.RotateTransform(270); 
    g.DrawImage(border, desRectW, desRectW, GraphicsUnit.Pixel); 
} 

Benim asıl resimdir:

enter image description here

Ama sonuç rotasyonlar tam olarak beklediğim gibi değil. 90 derece ilk kırmızı çizgiyi eksik, 270 derece ilk siyah sütunu eksik ve 180 derece de eksik. http://i.imgur.com/pzonx3i.png

Düzenleme:: En border2.bmp alabilirsiniz:

enter image description here

PS:

gibi görüntü ben ekli ben @Peter Duniho yorum olarak g.PixelOffsetMode = PixelOffsetMode.HighQuality; çalıştım, ama o da does bulundu t doğru çizin. Örnek: 4 satır beklediğimiz gibi aynı konumda başlamıyor.

g.TranslateTransform(50, 50); 

// LEFT - RIGHT border 
g.DrawLine(Pens.Red, 0, 0, 100, 0); 

// UP - BOTTOM border 
g.RotateTransform(90); 
g.DrawLine(new Pen(Color.FromArgb(128, Color.Blue)), 0, 0, 100, 0); 

// RIGHT-LEFT border 
g.RotateTransform(90); 
g.DrawLine(new Pen(Color.FromArgb(128, Color.Green)), 0, 0, 100, 0); 

// BOTTOM - UP border 
g.RotateTransform(90); 
g.DrawLine(new Pen(Color.FromArgb(128, Color.Gray)), 0, 0, 100, 0); 
+1

System.Drawing kayan nokta matrisini dahili olarak kullanır, bu da bir kayan nokta değeri integral bir piksele yuvarlandığında, tek tek hatalardan muzdarip olmasını sağlar. Graphics.PixelOffsetMode varsayılan değeri şanssız bir seçim oldu, bu yuvarlama eserler kurtulmak için değiştirmeniz gerekir. –

+0

@HansPassant: RotateTransform yaptıktan sonra başlangıç ​​koordinatı değiştirildi. Bir örnek ekledim. – KevinBui

+1

Ekran resminize baktığınızda, bu sizin sorununuz değil, ancak hala önemli bir adımı kaçırıyorsunuz: görüntünüzün monitörünüzle aynı __resolution__ olduğundan emin olmak için __need__. 96dpi vardır; Benim monitör 120dpi vardır ve görüntü dönme, döndürme ile veya rotasyon gibi görünüyor için düzeltmeden .. Bu resmi yükledikten sonra takın: 'kullanarak (Grafik gr = this.CreateGraphics()) img.SetResolution (gr.DpiX, gr. DpiY); '! – TaW

cevap

3

bu herhangi bir grafik API'si mutlaka zamanlarda kesin olmayan davranışlara yol açabilir optimizasyonları dahil etmek gidenler dışında, olur ve buraya böyle bir durumun içine çalıştıran görünüyor Gerçekten neden açıklayamam. Bunu Ayar

g.PixelOffsetMode = PixelOffsetMode.HighQuality; 

Half da çalışacaktır: Eğer görüntüleri çizmek önce, özel örnekte

, sorun, kodu aşağıdaki ifadeyi ekleyerek düzeltilebilir. Bu, HighQuality (veya teknik olarak HighQuality'un buna & hellip'e eşdeğerdir) ancak HighQuality kodunda daha açıklayıcı buluyorum :)).

Bu, bitmapin oluşturulmasını biraz yavaşlatır, ancak muhtemelen kullanıcılarınız tarafından algılanabilecek bir şekilde olmaz. PixelOffsetMode enumeration: .NET belgeleri bu ayarı açıklayan açısından çok yararlı olmasa da

, aynı özellik için yerli Win32 docs hafifçe fazla ayrıntı vardır. Açıklamadan, (0,0) 'daki pikselin mantıksal merkezi ile, bir kenarda dönerken (ve/veya başka bir kenarda bir piksel elde etmek) bir piksel kaybetmek mümkün olabilir. Half'a geçiş bunu düzeltir.

+0

Sanırım, onlar zaten eşdeğer oluyorlar, 'PixelOffsetModeHalf' kullanarak biraz daha net. Açıklama oldukça ilginç ve koordinatların ne anlama geldiğinin anlaşılması 'DrawImage' ve rotasyonların ötesine geçiyor. [Aynı sorun geçerlidir ”(http://stackoverflow.com/questions/36094055/adding-antialiasing/36095479#36095479) '' Pen 'ile anti-aliased pikselleri oluşturmayacak veya basitleştirmeyecek , örneğin 'Pen' havig bir tek veya' Genişlik '.. – TaW

+0

PixelOffsetMode.HighQuality da diğer durumlarda bazı beklenmeyen sonuç neden olur Örnek: 'g.DrawLine (Pens.Red, 0, 0, 100, 0) ; g.DrawLine (Pens.Blue, 0, 1, 100, 1); İlk satırda sadece mavi çizgi çizeceğini göreceksiniz. – KevinBui

+2

Lütfen (yukarıdaki yorumda) bir bağlantı verilen @TaW sorusunun cevabına ilişkin açıklamaya bakın. Alt satır, çizim yaparken çeşitli ayarlara bağlı olarak farklı durumlarda farklı eserler alacağınızdır. Döndürülmüş bitmapler çizerken olduğu gibi çizgiler çizerken aynı "PixelOffsetMode" değerini tutmanız gerekmez; İhtiyacınız olan sonuçları almak için ayarları gerektiği gibi ayarlamanız yeterlidir. –

0

Bazı şeyleri hesaba katmanız gerekir. Matrix.Rotatedocumentation

(2) varsayılan MatrixOrder() ek bir bağımsız değişkene geçersiz kılar kullanarak belirtilen zaman değil Prepend olduğu açıklandığı gibi

(1) RotateTransforms (mevcut kökenli de rotasyon uygulanır. Hangisi Sizin durumunuzda, sonuçta elde edilen dönüşüm dönüyor demektir, sonra çeviriniz.Örneğin

, boya olayda içine bu kodu koyarsanız:

var g = e.Graphics; 
var loc = new Point(128, 128); 
var rect = new Rectangle(0, 0, 64, 16); 

g.ResetTransform(); 
g.TranslateTransform(loc.X, loc.Y); 
g.FillRectangle(Brushes.Blue, rect); 

g.ResetTransform(); 
g.TranslateTransform(loc.X, loc.Y); 
g.RotateTransform(90); 
g.FillRectangle(Brushes.Red, rect); 

g.ResetTransform(); 
g.TranslateTransform(loc.X, loc.Y); 
g.RotateTransform(180); 
g.FillRectangle(Brushes.Green, rect); 

g.ResetTransform(); 
g.TranslateTransform(loc.X, loc.Y); 
g.RotateTransform(270); 
g.FillRectangle(Brushes.Magenta, rect); 

mavi dikdörtgen bu

enter image description here

döndürülmüş değildir alırsınız. Şimdi hemen orijini (sol üst nokta) sabitleyin ve saat yönünde dönmeye başlayın. Kırmızı (90), Yeşil (180) ve Magenta (270) dikdörtgenlerle tam olarak eşleşeceğini göreceksiniz.

Tüm bunların anlamı, bir dikdörtgen oluşturmak isterseniz, döndürülen dikdörtgenlere ek telafi (çeviri) uygulamanız gerektiğidir. Üst üste binen alanları nasıl ele almak istediğinize bağlıdır, ancak örnek için Kırmızı dikdörtgeni sağa Maviye sığdırmak istiyorsak, Mavi dikdörtgen Genişliği + orijinal dikdörtgenin Yüksekliğini X yönüne eklememiz gerekir. Diğer döndürülmüş dikdörtgenler için X, Y veya her ikisine benzer ek ofset uygulayabilirsiniz. Bu

var g = e.Graphics; 
var loc = new Point(128, 128); 
var rect = new Rectangle(0, 0, 64, 16); 

g.ResetTransform(); 
g.TranslateTransform(loc.X, loc.Y); 
g.FillRectangle(Brushes.Blue, rect); 

g.ResetTransform(); 
g.TranslateTransform(loc.X + rect.Width + rect.Height, loc.Y); 
g.RotateTransform(90); 
g.FillRectangle(Brushes.Red, rect); 

g.ResetTransform(); 
g.TranslateTransform(loc.X + rect.Width + rect.Height, loc.Y + rect.Width + rect.Height); 
g.RotateTransform(180); 
g.FillRectangle(Brushes.Green, rect); 

g.ResetTransform(); 
g.TranslateTransform(loc.X, loc.Y + rect.Width + rect.Height); 
g.RotateTransform(270); 
g.FillRectangle(Brushes.Magenta, rect); 

gibi kodunu değiştirmek durumunda

gerekli düzeltmeleri uygulayabilirsiniz umut, tüm bu anladığınızda yeni sonuç

enter image description here

olacak, örnek tamamlamak için Beton koduna.

İlgili konular