2014-01-21 2 views
0

UPDATE : 코드는 질문C - 바이 리니어 스케일링 (보간)에 의해 바이트 바이트

의 말

내가 지정된 이미지 크기를 조절하고에 결과를 표시하도록되어 간단한 응용 프로그램을 쓰고 있어요에서 편집을 참조 이제 OK입니다 화면. 이미지 로딩, 표시 등은 SDL을 통해 이루어 지지만, 여전히 스케일링 기능에 문제가있어 - 횡설수설을 일으킨다.

24 비트 이미지에서 작동해야하므로 uint8_t 캐스팅과 바이트 단위 계산이 필요합니다.

#include <stdint.h> 
void blin(uint8_t* pixelsIn, uint8_t* pixelsOut, int w, int h, float scale) 
{ 
    int index1, index2; 
    int w2, h2; 
    int i, j, k; 
    float x, y; 
    float t; 
    int p1, p2; 

    w2 = (int)(scale*w + 0.5); 
    h2 = (int)(scale*h + 0.5); 
    p1 = w*3; 
    if(p1%4) p1 += (4-p1%4); 
    p2 = w2*3; 
    if(p2%4) p2 += (4-p2%4); 
    for(i=0;i<h2;i++) //line 
    { 
     index2=i*p2; 
     for(j=0;j<w2;j++) //column 
     { 
      x=((float)(j))/scale; 
      index1=(int)(x) * 3; 
      x-=(int)(x); 
      y=((float)(i))/scale; 
      index1+=(int)(y) * p1; 
      y-=(int)(y); 
      for(k=0;k<3;k++) //for color in R, G, B 
      { 
       t = (float)(pixelsIn[index1]) * (1.0-x)*(1.0-y); 
       t += (float)(pixelsIn[index1+3]) * (x)*(1.0-y); 
       t += (float)(pixelsIn[index1+p1]) * (1.0-x)*(y); 
       t += (float)(pixelsIn[index1+p1+3]) * (x)*(y); 
       pixelsOut[index2] = (uint8_t)(t); 
       index1++; 
       index2++; 
      } 
     } 
    } 
} 

편집 : 분명한 오류 index2는 0이 아니며 x는 3 (픽셀 당 바이트)을 곱하지 않고 계산되었습니다.

Edit2가 :하지만 이미지는이 이전과 규모에 대한 후 = 1.0 (JPG를 단지 빠른 업로드), 아직 제대로 조정되지 않습니다 2 문제 SDL_Surface 픽셀 구조 내에서 4 바이트 정렬 이제는 매력처럼 작동합니다 (코드는 업데이트 됨). 24 비트 이미지에서만 작동하도록 설계되었습니다. 최상의 대답에 대한 설명을 참조하십시오.

index1=(int)(x); 

해야한다 : - -이 :

+0

괜찮습니다. 아마도'blin (src, dst, width_src, height_src, width_dst, height_dst); 프로토 타입을 사용할 때 무슨 일이 벌어 질지 생각해보아야한다.'dst'가 정확히 적당한 공간을 확보하고'scale_w'와'scale_h'를 따로 계산한다. 각 차원에 대해 또한 크기를 줄인다면 대략 <0.7의 이미지를 미리 필터링해야합니다. –

+0

당분간 양쪽 눈금을 동일한 눈금만큼 확대합니다. – MJBogusz

+0

편집 시간이지나 ... 다운 스케일링시 아무런 의미가없는 보간법을 잘 알고 있으며 통합 스케일을 사용하는 것이 단순화 및 프로젝트 가정입니다. 또한 나중에 쉽게 사용할 수 있습니다. 코드가 ASM으로 다시 작성됩니다. – MJBogusz

답변

0

나는이 줄을 생각

또한
index1=(int)(x)*3; 

가, 보폭은 행의 제 1 픽셀, width.sizeof(pixel)과 동일하다고 가정하지 않습니다를 할 수있다

void blin(uint8_t* pixelsIn, uint8_t* pixelsOut, int w, int h, float scale, int input_stride, int output_stride) 
{ 
    int index1, index2; 
    int w2, h2; 
    int i, j, k; 
    float x, y; 
    float t; 

    w2=(int)(scale*w + 0.5); 
    h2=(int)(scale*h + 0.5); 
    index2=0; 
    for(i=0;i<h2;i++) //line 
    { 
     int pixelindex2=index2; 
     for(j=0;j<w2;j++) //column 
     { 
      x=((float)(j))/scale; 
      index1=(int)(x)*3; 
      x-=(int)(x); 
      y=((float)(i))/scale; 
      index1+=(int)(y) * input_stride; 
      y-=(int)(y); 
      for(k=0;k<3;k++) //for color in R, G, B 
      { 
       t = (float)(pixelsIn[index1]) * (1.0-x)*(1.0-y); 
       t += (float)(pixelsIn[index1+3]) * (x)*(1.0-y); 
       t += (float)(pixelsIn[index1+w*3]) * (1.0-x)*(y); 
       t += (float)(pixelsIn[index1+w*3+3]) * (x)*(y); 
       pixelsOut[pixelindex2] = (uint8_t)(t); 
       index1++; 
       pixelindex2++; 
      } 
     } //column 
     index2+=output_stride; 
    } //line 
} 

- : 워드/더블 워드로 정렬하는 것은/등 경계, 그래서 코드를 변경할 것및 output_stride은 연속 라인의 시작 사이의 바이트 수이며 width * 3과 같지 않을 수 있습니다.

다른 이미지 형식을 처리 할 수 ​​있도록 '3'상수를 변수로 만드는 것을 고려할 수도 있습니다.

+0

네, 이것이 제 2의 주요 문제였습니다 - 나는 그것을 어느 정도 동시에 발견했습니다. – MJBogusz

+0

(첫 번째 index2는 0이 아니며 편집 참조). 그러나 1.0, 1.2, 1.4 등에서는 잘못된 옵셋 계산이 여전히 존재합니다. 스케일링은 괜찮지 만 1.1, 1.3 등에서는 아마도 쓰는 동안 눈에 보이는 변화가있을 것입니다 (http://i.imgur.com/3WFZ7w3.png).). 답변을 찾으면 나중에 참조 할 수 있도록 여기에 코드를 추가하고 해당 코드를 업데이트합니다. 지금까지는 좋고 간단한 bilinear 스케일링 C 코드를 발견했습니다. PS. 입력 및 짧은 편집 시간에 지독한 자동 전송. – MJBogusz

+0

@ JohnSmith105127 : 스트라이드 문제가 발생했다고 생각합니다 (예 : 줄의 픽셀 수 = 바이트 수). 답변을 업데이트했습니다. – Skizz