2017-03-12 6 views
0

내가하려는 일의 요구 때문에 픽셀 용 맞춤 클래스가 있어야합니다.빠른 맞춤 픽셀 형식을 만드는 방법

byte red 
byte green 
byte blue 
int brightness 
int X 
int Y 

내가 좌표가 필요합니다, 그래서 나는 단지 내가 그리는 데 필요한 픽셀로 구성 배열을 만들 수 있습니다 : 각 픽셀을 위해 나는 있습니다. 예를 들어, 선이있는 경우 대각선으로 이동하므로 선을 그릴 필요가있는 픽셀의 1 차원 배열 만 갖기를 원합니다. 나머지 픽셀을 스캔하지 않아도되므로 불필요한 검색을 피할 수 있습니다. 현재의 경우, 많은 폴리곤을 갖게 될 것입니다. 폴리곤은 특정 순서와 방식으로 이미지에 적용되어야합니다. 이것은 게임 엔진을위한 것이므로 어쨌든 사용하지 않을 픽셀을 통한 스캔을 피하려고해야합니다.

그러나 Pixel 클래스의 데이터를 사용하면 작업 속도가 느려집니다. 정말 천천히. 어쩌면 비트 맵이 생성되는 기본 픽셀 형식보다 수백 배 느려질 수 있습니다. 이와 함께 픽셀을 변경하는 작업 자체도 매우 느립니다.

각 픽셀의 색상, 밝기 및 좌표에 대한 모든 정보를 저장하면서 어떻게 픽셀 생성 및 조작 속도를 향상시킬 수 있습니까? 부수적 인 질문 : System.Drawing에서 픽셀 형식이 어떻게 작동하는지 설명 할 수있는 곳이 있습니까?

답변

0

스트라이드 패턴으로 액세스하는 많은 클래스 인스턴스 대신에 싱글 톤의 내부 배열에 액세스하기 위해 []을 오버로드 할 수 있습니다. 따라서 pixels[n].X은 "픽셀"객체의 내부 배열 또는 구조체 배열에 액세스 한 다음 X를 빠르게 꺼냅니다.

구조체의 모든 픽셀 속성을 갖습니다. 픽셀 클래스에서 인덱싱을 사용하여 해당 구조체에 액세스합니다. 구조체 배열에 해당 구조체를 넣으십시오.

StructLayoutAttribute를 사용하여 더 나은 액세스 성능을 위해 구조체를 적절한 크기 (및 정렬)로 패킹하십시오.

구조체의 필드를 재정렬하면 (아마도) 적은 메모리 조작으로 모든 데이터를 읽을 수 있습니다.

함수에서 모든 속성을 사용하는 경우 유용 할 수 있습니다.


대신 구조체의 배열, 당신은 모든 픽셀 (게임 엔진의 할당에 의해 주어진) 및 전환 오버 헤드를 elliminate에 더 큰 덩어리로 읽을 관리되지 않는 메모리 영역을 사용할 수 있습니다. (단 1 년 전체 구조체를 읽을 수 있습니다 또는 2 개의 내장로드 명령어). 포인터 및 안전하지 않은 컨텍스트를 사용하여 더 큰 청크로 업데이트하거나 임시 결과를 누적하십시오.

int X 
int Y 
int brightness 
byte red 
byte green 
byte blue 
byte alpha 

은 16 바이트 구조체 경계에 적합해야합니다.


사용하려는 경우 색상 별도로 좌표, 또는 일부 속성은 항상 사용되지 않습니다은 다음 픽셀에 대해 반복하는 한 적은 걸음 요소를 만드는, 그래서 당신이 그것을 분리 및 프리미티브의 배열로 사용한다 . 어떤 공간 검색 알고리즘에서 X와 Y를 함께 사용하지만 색상이 아닌 경우 X와 Y가 각각 구조체의 다른 배열 (클래스가 아닌)에 재 그룹화되도록 할 수 있으므로 색상 속성은 얻을 수 없습니다 당신의 방식대로 성능면에서.


당신은 X에 액세스

,

public class MyPixel{ 
    public float X{ 
       get{ /* access an array or 
         array of structs or 
         unmanaged memory */} 
       set{ /* same */} 
    } 

    // for unrolled loops 
    public static void BatchUpdateXY(float[] source,int pixelStart,int pixelEnd) 
    { /* copy from source */} 
} 

하더라도 세터 게터 비용 50 % 성능 대신 pixels.X[i]을 시도하고 (배열 또는 관리되지 않는 메모리) 최대 속도를 가질 수 있도록.


상위 솔루션에서 순수한 C++ 배열을 사용하면 새 픽셀을 추가하는 것이 어려워 지므로 C++ 측에서 벡터 나 비슷한 컨테이너가 필요할 수 있습니다.

0

사실 그리기 기능이 최적화 된 방식으로 수행되고 있습니다 (하드웨어 가속화). 고유 한 그리기 기능이 필요한 이유 (예 : 대각선 또는 다각형을 만들기 위해 각 픽셀을 계산)가 확실하지 않습니다.

각 픽셀을 계산하고 저장하는 대신 연결할 필요가있는 점만 저장 한 다음 그리기 기능을 호출하여 작업을 수행 할 수 있습니까?

정말로 직접해야하는 경우, 아마도 가장 좋은 방법은 크기가 너비 * 32 비트 인 RGBA 정수 32 비트의 배열 또는 벡터를 만드는 것입니다.이 정수는 처리 속도가 훨씬 빠릅니다.

그리고 실제로는 비트 맵이므로 메모리에 비트 맵을 만들고 표준 그리기 함수를 사용하여 해당 비트 맵 (RGBA 포인트가있는 배열)에 선을 그립니다. 끝에있는 모든 픽셀을 한 번 이동하면 검색, 정렬, 정렬 및 성장이 필요한 1D 배열에서이 작업을 수행하는 것보다 훨씬 빠릅니다.

'0이 아닌'모든 픽셀을 한 번에 이미지로 이동하려면 TransparentBlt()을 사용할 수도 있습니다.