/*------------------------------------------------------------------------------------------------------------ * ビットマップファイルを書き出す * * path: 書き出すビットマップファイル */ void Bitmap::writeFile(const char *path) const { FILE *ofp = fopen(path, "wb"); if (ofp == 0) { perror("fopen"); fprintf(stderr, "file: %s\n", path); throw MyError("bitmap file open failed", __FUNCTION__); } writeFileHeader(ofp); writeInfoHeader(ofp); writeBitmapData(ofp); fclose(ofp); }
void BitmapWriter::writeBitmap(Bitmap & bitmap, const char * filePath) { FILE * file = fopen(filePath, "wb"); writeFileHeader(bitmap.fileheader, file); writeInfoHeader(bitmap.infoheader, file); byte zero = 0; for (int i = 0; i < bitmap.height; i++) { for (int j = 0; j < bitmap.width; j++) writePixel(bitmap.get(j, i), file); for (int j = 0; j < bitmap.paddingZeros; j++) fwrite(&zero, sizeof(byte), 1, file); } fclose(file); }
int cropImage(FILE* inFile, struct bmpFileHeader* fileHead, struct bmpInfoHeader* infoHead, char* outFileName, int cropWidth, int cropHeight, int cropStart[]) { // check that cropping parameters make sense if (((cropWidth + cropStart[0]) > infoHead->width) || ((cropHeight + cropStart[1]) > infoHead->height)) { fprintf(stderr, "Cropping parameters incorrect.\n"); return EXIT_FAILURE; } // open file for writing FILE *outFile = fopen(outFileName, "w+"); // check that file opened okay if (outFile == NULL) { fprintf(stderr, "Unable to open file: %s for writing.\n", outFileName); return EXIT_FAILURE; } // store old width/height for use in loop LONG oldWidth = infoHead->width; LONG oldHeight = infoHead->height; // calculate padding used in old image int oldPadding = (4 - (oldWidth*sizeof(struct pixel) % 4)) % 4; // calculate padding to be used in new image int newPadding = (4 - (cropWidth*sizeof(struct pixel) % 4)) % 4; // new image size infoHead->imageSize = (cropWidth*sizeof(struct pixel) + newPadding)*cropHeight; // file size fileHead->fileSize = sizeof(struct bmpFileHeader) + sizeof(struct bmpInfoHeader) + infoHead->imageSize; // new dimensions infoHead->width = cropWidth; infoHead->height = cropHeight; // write the headers to the output file, checking for errors if (writeFileHeader(fileHead, outFile) != 0) { fprintf(stderr, "Unable to write file header.\n"); return EXIT_FAILURE; } if (writeInfoHeader(infoHead, outFile) != 0) { fprintf(stderr, "Unable to write info header.\n"); return EXIT_FAILURE; } // to store pixel being worked on struct pixel* curPixel = NULL; // run through old pixels, discarding those which are to be cropped // and writing the rest to file for (int i = 0; i < oldHeight; i++) { // only run through line if we're out of region to be cropped if (!(i < (oldHeight - cropStart[1] - cropHeight) || i > (oldHeight - cropStart[1]))) { for (int j = 0; j < oldWidth; j++) { // only write to file if not in cropped region if (!(j < cropStart[0] || j > cropStart[0] + cropWidth)) { // read in the current pixel curPixel = getPixel(inFile); // make sure read worked if (curPixel == NULL) { fprintf(stderr, "Unable to read pixel.\n"); return EXIT_FAILURE; } // write current pixel, checking for error if (writePixel(curPixel, outFile) != EXIT_SUCCESS) { fprintf(stderr, "Unable to write pixel.\n"); return EXIT_FAILURE; } } else { // move old file on by a pixel fseek(inFile, sizeof(struct pixel), SEEK_CUR); } } } else { // move old file on by width + padding fseek(inFile, oldWidth*sizeof(struct pixel) + oldPadding, SEEK_CUR); } // move old file on by padding fseek(inFile, oldPadding, SEEK_CUR); // add padding to new file for (int k = 0; k < newPadding; k++) { fputc(0x00, outFile); } } // free memory allocated to current pixel storage free(curPixel); // close the output file, checking for error if (fclose(outFile) != 0) { fprintf(stderr, "Unable to close output file: %s.\n", outFileName); return EXIT_FAILURE; } // if program gets to here, everything is okay return EXIT_SUCCESS; }
/* Applies a threshold filter to a BMP file and writes the result to another. Takes care of opening and closing the output file. */ int applyThreshold(FILE* inFile, struct bmpFileHeader* fileHead, struct bmpInfoHeader* infoHead, char* outFileName, float threshold) { // check that threshold value is in range if (threshold < 0.0 || threshold > 1.0) { fprintf(stderr, "Threshold value not in range.\n"); return EXIT_FAILURE; } // open file for writing FILE *outFile = fopen(outFileName, "w+"); // check that file opened okay if (outFile == NULL) { fprintf(stderr, "Unable to open file: %s for writing.\n", outFileName); return EXIT_FAILURE; } // write the headers to the output file, checking for errors if (writeFileHeader(fileHead, outFile) != 0) { fprintf(stderr, "Unable to write file header.\n"); return EXIT_FAILURE; } if (writeInfoHeader(infoHead, outFile) != 0) { fprintf(stderr, "Unable to write info header.\n"); return EXIT_FAILURE; } // calculate amount of padding added to width int padding = (4 - (infoHead->width*3 % 4)) % 4; // to store pixel being worked on struct pixel* curPixel = NULL; // run through pixels, modifying and saving them to out file for (int i = 0; i < infoHead->height; i++) { for (int j = 0; j < infoHead->width; j++) { // get a pixel curPixel = getPixel(inFile); // make sure we actually got a pixel if (curPixel == NULL) { fprintf(stderr, "Unable to get pixel.\n"); return EXIT_FAILURE; } double maxPixelValue = pow(2, infoHead->colourDepth/3) - 1; // calculate individual intensity values for each colour double redIntensity = (curPixel->red)/maxPixelValue; double greenIntensity = (curPixel->green)/maxPixelValue; double blueIntensity = (curPixel->blue)/maxPixelValue; // determine if pixel above thresh, make it black/white accordingly if ((redIntensity + greenIntensity + blueIntensity)/3.0 > threshold) { const uint32_t white = 0xFFFFFF; // write pixel, checking for error if (fwrite(&white, 3, 1, outFile) != 1) { fprintf(stderr, "Unable to write white pixel to file.\n"); return EXIT_FAILURE; } } else { const uint32_t black = 0x000000; // write pixel, checking for error if(fwrite(&black, 3, 1, outFile) != 1) { fprintf(stderr, "Unable to write black pixel to file.\n"); return EXIT_FAILURE; } } } // move in-file on by padding amount fseek(inFile, padding, SEEK_CUR); // add padding to out-file for (int k = 0; k < padding; k++) { fputc(0x00, outFile); } } // free memory allocated to pixel storage free(curPixel); // close the output file, checking for error if (fclose(outFile) != 0) { fprintf(stderr, "Unable to close output file: %s.\n", outFileName); return EXIT_FAILURE; } // if program gets to here, everything is okay return EXIT_SUCCESS; }