안녕하세요 저는 640x480 비트 맵 이미지를 320x240 이미지로 축소하는 프로그램을 진행하고 있습니다. 나는 잠시 동안이 문제를 연구 해왔다. 그러나 내가 발견 한 좋은 예는 모두 이미지의 크기를 늘리는 것이었다.이미지 크기를 축소하는 방법은 무엇입니까?
(여기 참조 : http://cboard.cprogramming.com/c-programming/154737-help-program-resize-image.html)
난 내에서 수행해야 할 것과 그 프로그램에서 수행 한 것을 번역 어려움을 겪고 있어요. 그러나 생성 된 이미지가 원래의 매우 왜곡 된 버전이며,
include stdio.h
include stdlib.h
include string.h
include math.h
pragma pack(push, 1)
typedef struct tagBITMAPFILEHEADER
{
unsigned short bfType; //specifies the file type
unsigned int bfSize; //specifies the size in bytes of the bitmap file
unsigned short bfReserved1; //reserved; must be 0
unsigned short bfReserved2; //reserved; must be 0
unsigned int bfOffBits; //species the offset in bytes from the bitmapfileheader to the bitmap bits
} BITMAPFILEHEADER;
pragma pack(pop)
pragma pack(push, 1)
typedef struct tagBITMAPDIBHEADER
{
unsigned int biSize; //specifies the number of bytes required by the struct
int biWidth; //specifies width in pixels
int biHeight; //species height in pixels
unsigned short biPlanes; //specifies the number of color planes, must be 1
unsigned short biBitCount; //specifies the number of bit per pixel
unsigned int biCompression;//spcifies the type of compression
unsigned int biSizeImage; //size of image in bytes
int biXPelsPerMeter; //number of pixels per meter in x axis
int biYPelsPerMeter; //number of pixels per meter in y axis
unsigned int biClrUsed; //number of colors used by th ebitmap
unsigned int biClrImportant; //number of colors that are important
} BITMAPDIBHEADER;
pragma pack(pop)
pragma pack(push, 1)
typedef struct
{
int rgbtBlue;
int rgbtGreen;
int rgbtRed;
}
RGBTRIPLE;
pragma pack(pop)
int main()
{
FILE *input, *output;
BITMAPDIBHEADER inputdibHeader;
BITMAPFILEHEADER inputfileHeader;
BITMAPDIBHEADER outputdibHeader;
BITMAPFILEHEADER outputfileHeader;
int greenValue = 0;
int blueValue = 0;
int redValue = 0;
fopen_s(&output, "test.bmp", "wb");
if (output == NULL){
return NULL;
}
fopen_s(&input, "lolcat.bmp", "rb");
if (input == NULL)
return NULL;
rewind(input); // rewind the file before reading it again
fread(&(inputfileHeader), sizeof(BITMAPFILEHEADER), 1, input);
fread(&(inputdibHeader), sizeof(BITMAPDIBHEADER), 1, input);
rewind(input); // rewind the file before reading it again
fread(&(outputfileHeader), sizeof(BITMAPFILEHEADER), 1, input);
fread(&(outputdibHeader), sizeof(BITMAPDIBHEADER), 1, input);
outputdibHeader.biWidth = inputdibHeader.biWidth *.5;
outputdibHeader.biHeight = inputdibHeader.biHeight *.5;
outputfileHeader.bfSize = outputdibHeader.biWidth * outputdibHeader.biHeight;
outputdibHeader.biSizeImage = inputdibHeader.biSizeImage *.5;
fwrite(&(outputfileHeader), sizeof(BITMAPFILEHEADER), 1, output);
fwrite(&(outputdibHeader), sizeof(BITMAPDIBHEADER), 1, output);
rewind(input);
fseek(input, inputfileHeader.bfOffBits, SEEK_SET);
fseek(output, outputfileHeader.bfOffBits, SEEK_SET);
int oldheight = inputdibHeader.biHeight;
int oldwidth = inputdibHeader.biWidth;
int i;
int timeswriten = 0;
int oldPad = (4 - ((inputdibHeader.biWidth * sizeof(RGBTRIPLE)) % 4)) % 4;
int newPad = (4 - ((outputdibHeader.biWidth * sizeof(RGBTRIPLE)) % 4)) % 4;
// iterate over infile's scanlines
for (int i = 0; i < abs(oldheight); i++)
{
if (i % 2){
// iterate over pixels in scanline
for (int j = 0; j < oldwidth; j++)
{
// temporary storage
RGBTRIPLE triple;
fread(&triple, sizeof(RGBTRIPLE), 1, input);
if (j % 2){
fwrite(&triple, sizeof(RGBTRIPLE), 1, output);
}
// skip over any input padding
fseek(input, oldPad, SEEK_CUR);
}
}
}
fclose(input);
fclose(output);
}
현재이 코드가 유효한 비트 맵 이미지를 생성한다 : 여기서 SOFAR 내 코드이다. 임 꽤 확신이 내 새로운 이미지에서 픽셀을 생략하는 방법으로 인해 있지만이 올바른 접근 방식에 있어야하는지 잘 모르겠습니다. 내 모든 질문을 통해 누구나 내가 어떻게 픽셀을 생략해야한다고 설명 할 수 있습니까?
업데이트
지금 내가 무엇을 목표로하고하는 것은 하나 개의 픽셀에 평균 2 × 2 픽셀 것을 알고 있지만 나는이 작업을 수행하는 방법에 대한 좋은 예를 찾을 수 없습니다. 이 과정을 설명해 줄 수 있습니까?
업데이트 2PeterT에게 감사드립니다. 다음 코드는 내 출력에 의해 정확하다는 것을 알고 있습니다.
RGBTRIPLE *line_a = (RGBTRIPLE*)malloc(inputdibHeader.biWidth * sizeof(RGBTRIPLE)); /* check malloc() */
RGBTRIPLE *line_b = (RGBTRIPLE*)malloc(inputdibHeader.biWidth *sizeof(RGBTRIPLE)); /* check malloc() */
RGBTRIPLE *dest_line = (RGBTRIPLE*)malloc(outputdibHeader.biWidth * sizeof(RGBTRIPLE));
/* move through the target array line by line, consuming two lines from the source
image at a time */
/* also assuming you verified the source image is exactly 2x the size of the dest
malloc() */
for (i = 0; i < outputdibHeader.biHeight; ++i)
{
fread(&(line_a), sizeof(RGBTRIPLE), inputdibHeader.biWidth, input); /* read scanline & advance file pointer, err check in func */
fread(&(line_b), sizeof(RGBTRIPLE), inputdibHeader.biWidth, input);/* read scanline & advance file pointer, err check in func */
for (j = 0; j < outputdibHeader.biWidth; ++j)
{
bilinear_filter(&(dest_line[j]), &(line_a[j * 2]), &(line_a[(j * 2) + 1]), &(line_b[j * 2]), &(line_b[(j * 2) + 1]));
}
fwrite(&(dest_line), sizeof(RGBTRIPLE), outputdibHeader.biWidth, output);
/* or something... point is we're creeping through the files scaline by scanline,
and letting another function handle it to keep this code more intelligble */
}
fclose(input);
fclose(output);
}
void bilinear_filter(RGBTRIPLE *dest, RGBTRIPLE *A, RGBTRIPLE *B, RGBTRIPLE *C, RGBTRIPLE *D)
{
/* assuming 0888 ARGB */
dest->Red = (A->Red + B->Red + C->Red + D->Red)/4;
dest->Green = (A->Green + B->Green + C->Green + D->Green)/4;
dest->Blue = (A->Blue + B->Blue + C->Blue + D->Blue)/4;
}
나는이 문제가 지금 여기 내 헤더 생성에 거짓말입니다 수 있습니다 생각
fread(&(inputHeader), sizeof(TwoHeader), 1, input);
inputfileHeader = inputHeader.fileHeader;
inputdibHeader = inputHeader.dibHeader;
rewind(input); // rewind the file before reading it again
fread(&(outputHeader), sizeof(TwoHeader), 1, input);
outputfileHeader = outputHeader.fileHeader;
outputdibHeader = outputHeader.dibHeader;
outputdibHeader.biWidth = inputdibHeader.biWidth *.5;
outputdibHeader.biHeight = inputdibHeader.biHeight *.5;
//outputfileHeader.bfSize = inputfileHeader.bfSize - (inputdibHeader.biWidth*inputdibHeader.biHeight) + outputdibHeader.biWidth*outputdibHeader.biHeight;
outputfileHeader.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPDIBHEADER)+outputdibHeader.biSizeImage;
//outputdibHeader.biSizeImage = inputdibHeader.biSizeImage * .25;
//outputdibHeader.biXPelsPerMeter = inputdibHeader.biXPelsPerMeter * .5;
//outputdibHeader.biYPelsPerMeter = inputdibHeader.biYPelsPerMeter * .5;
//fwrite(&(outputfileHeader), sizeof(BITMAPFILEHEADER), 1, output);
//fwrite(&(outputdibHeader), sizeof(BITMAPDIBHEADER), 1, output);
fwrite(&(outputHeader), sizeof(TwoHeader), 1, output);
rewind(input);
fseek(input, inputfileHeader.bfOffBits, SEEK_SET);
fseek(output, outputfileHeader.bfOffBits, SEEK_SET);
사면 모든 의견 나는 확실하지 오전의 대부분은 이전 코드 또는 코드.
아마도 문제와 관련이 없으므로 (더 자세히 설명하고 싶을 수 있습니다.) 이미지의 너비와 높이를 반으로 줄이면 새로운 'biSizeImage'는 1/2이 아니며 실제로는 1/2 * 1/2 = 1/4 크기. 주로 RGB 트라이 플릿은'int'가 아닌'unsigned char'이어야합니다. – usr2564301
다양한 수준의 효율성과 품질을 갖춘 알고리즘이 많이 있습니다. 꽤 광범위한 주제입니다. 이것은 당신에게 생각할 몇 가지 사항을 줄 수 있습니다 : http://stackoverflow.com/questions/6133957/image-downsampling-algorithms –
@RetiredNinja 적어도 많은 도움을 주셔서 감사합니다, 지금은 내가 뭘 찾아야하는지에 대한 아이디어가 있습니다. 불행하게도이 페이지는 실제로 알고리즘이 어떻게 사용되는지에 대한 좋은 예는 보여주지 않습니다. 나는 하나를 찾을 것이다. 당신이 알고있는 일이 있다면 당신은 그것을 연결시킬 수 있습니다. – Noob