2011-02-14 1 views
8

Related Question크기 조정 된 이미지의 XY 좌표 및 높이/너비를 원래 크기의 이미지로 변환하려면 어떻게해야합니까?

나는 C#으로 링크 된 질문과 같은 것을하려고합니다. 크기 조정 된 이미지를 보여 주며 사용자가자를 영역을 선택할 수있게합니다. 그러나, 나는 스케일링 된 이미지 선택에서 x1y1, x2y2 좌표를 가져 와서 원본에서 자르기 만 할 수는 없습니다. 나는 다른 질문에서와 같이 기본적인 수학을 시도해 보았지만 분명히 올바른 접근법이 아니었다.

편집

원본 이미지 크기 : w = 1024 h = 768

스케일 이미지 크기 : 나는 이미지로 시작 w = 550 h = 412

는 1024을 말한다. 550x550 상자에 가능한 한 크게 넣기를 바랍니다. 다음 방법을 사용하여 가로 세로 비율을 유지하면서 크기 조정 된 이미지 크기를 가져옵니다. 그런 다음 새로운 차원에 대한 기본 크기 조정을 수행합니다.

선택 영역은 (0,0)에서 (100,100)까지 선택할 수 있습니다.

private static Rectangle MaintainAspectRatio(Image imgPhoto, Rectangle thumbRect) 
{ 
    int sourceWidth = imgPhoto.Width; int sourceHeight = imgPhoto.Height; int sourceX = 0; int sourceY = 0; int destX = 0; int destY = 0; 

    float nPercent = 0; 
    float nPercentW = 0; 
    float nPercentH = 0; 

    nPercentW = ((float)thumbRect.Width/(float)sourceWidth); 
    nPercentH = ((float)thumbRect.Height/(float)sourceHeight); 

    //if we have to pad the height pad both the top and the bottom 
    //with the difference between the scaled height and the desired height 
    if (nPercentH < nPercentW) 
    { 
     nPercent = nPercentH; 
     destX = (int)((thumbRect.Width - (sourceWidth * nPercent))/2); 
    } 
    else 
    { 
     nPercent = nPercentW; 
     destY = (int)((thumbRect.Height - (sourceHeight * nPercent))/2); 
    } 

    int destWidth = (int)(sourceWidth * nPercent); 
    int destHeight = (int)(sourceHeight * nPercent); 

    Rectangle retRect = new Rectangle(thumbRect.X, thumbRect.Y, destWidth, destHeight); 
    return retRect; 
} 
+1

여기서는 크기 조정 된 이미지의 0입니까? 왼쪽 상단 또는 왼쪽 하단? –

+0

왼쪽 상단으로 가정합니다. – scottm

+1

변환 (2x2 행렬)을 사용하여 이미지의 크기를 조절합니다. 해당 행렬의 역함수를 사용하여 좌표 변환을 수행합니다. 원본 이미지 크기, 위치 및 변형 된 이미지 크기, 위치에 대한 구체적인 수치 예제를 제공하십시오. 일부 사람들은 그런 생각을하기 쉽고 일부 모호성은 제거합니다. –

답변

7

반올림 오류가 발생했습니다 ...
- (위, 왼쪽) 좌표를 원본으로 다시 조정할 때 반올림해야합니다 (왼쪽 위).
은 - 원래로 다시 (아래, 오른쪽) 좌표를 확장 할 때, 당신은

원으로 12 × 12 그리드의 간단한 예제를 가지고, 그리고 4 × 4 (오른쪽 아래 방향으로) 반올림합니다 그리드를 축소 된 버전으로 만듭니다.
- 스케일 된 버전 = (3,3) :(8,8)
- 2x2 픽셀 = 크기 조정 된 영역의 면적의 25 %
- 6x6 픽셀 = 원본 버전의 면적의 25 %

단순히 같은 배율 인수로 곱하면이 (3,3) :(6,6)이됩니다.


OriginalTop = INT (ScaledTop * YScalingFactor);
OriginalLeft = INT (ScaledLeft * XScalingFactor);

OriginalBottom = INT ((ScaledBottom + 1) * YScalingFactor) - 1;
OriginalRight = INT ((ScaledRight + 1) * XScalingFactor) - 1;


편집 :

나는 picutre을 그릴 것 말을 노력하고있어 설명하는 더 좋은 방법. 그리고 나는 아스키 아트를 빨아 먹는다. 여기에 단어가있는 또 다른 시도가 있습니다.

픽셀은 중요하지 않습니다.그것은 그 안에 작은 사각형입니다.

픽셀을 사용하여 사각형의 왼쪽 위를 나타내면 픽셀의 가장 왼쪽 상단에서부터의 영역을 포함하게됩니다.

당신이 사각형의 오른쪽 아래을 표현하는 픽셀을 사용

, 당신은이 지역에게 오른쪽 아래 픽셀의 대부분의 지점에있는 모든 방법을 포함하고 있습니다. 제 (12 × 12)을 사용


는 => (4 × 4) 실시 예 또, 각 스케일링 된 픽셀은 원래의 픽셀의 전체의 3 × 3 세트를 나타낸다. 왼쪽 상단에 대해 이야기 할 때 원본에서 3x3 픽셀 그룹의 왼쪽 상단 픽셀을 선택합니다. 오른쪽 하단에 대해 이야기 할 때 원본에서 3x3 픽셀 그룹의 오른쪽 하단을 선택합니다.


편집 : 단지 정수를 사용.


유일한 고려

NewTop = (( OldTop ) * NewHeight/OldHeight); 
NewLeft = (( OldLeft ) * NewWidth/OldWidth); 

NewBottom = ((OldBottom + 1) * NewHeight/OldHeight) - 1; 
NewRight = ((OldRight + 1) * NewWidth/OldWidth) - 1; 

는 곱셈 후 데이터 유형을 오버 플로우하지 않도록하고있다. 하지만 이미지가 없다면 이미지가 아닙니다.

+0

사실 일 수 있습니다. 내 작물은 일반적인 지역에서 나오지만, 꽤 잘 어울리지는 않습니다. – scottm

+0

스케일링 계수는 어떻게 결정합니까? 그냥 축소 되었습니까? – scottm

+0

그래, 그냥 더블 또는 무언가 멋지고 플로트 정확한 것으로 유지하십시오. (그리고 다른 X와 Y 스케일링 팩터를 계산하십시오) – MatBailie

0

당신은 스케일 이미지에 대한 퍼센트의 위치를 ​​얻을 스케일 없음의 이미지 좌표에 다시 켤 수 있습니다 : 당신이 실제로 것 같은데요 좀 더 세부없이

pX1 = scaledX1/scaled_width 
pY1 = scaledY1/scaled_height 

unscaledX1 = ceiling(unscaled_width * pX1) 
unscaledY1 = ceiling(unscaled_height * pY1) 
+0

직관적이지만, 오른쪽 하단 좌표는 다루지 않습니다. 픽셀은 포인트가 아니며 작은 사각형입니다. 픽셀의 사각형의 오른쪽 아래에 새로운 좌표 표현을 캡처하려고합니다. – MatBailie

+0

이 방법을 사용하면 내가 어디에 있는지 알 수 있습니다. 그것은 여전히 ​​일반적인 영역에 있지만 꽤 아닙니다. – scottm