簡體   English   中英

在 c 中使用 libpng 編寫正弦波

[英]Writing sine wave using libpng in c

使用 libpng。 我寫了一個代碼(其中大部分是從How to change rgb values from a png image with libpng using c?中復制粘貼的)。 我的嘗試是用波形寫一個 png,但是在我的正弦波中有些地方很不對勁:

微弱的正弦波

生成此 png 的代碼:

#include <stdio.h>
#include <math.h>
#include <stddef.h>
#include "png.h"
#include <stdlib.h>
//#define _USING_MATH_DEFINES

#define ERROR 1


int width, height;

png_byte color_type;
png_byte bit_depth;
png_bytep *row_pointers;

void read_png_file(char *filename) {
  FILE *fp = fopen(filename, "rb");
  if(!fp) abort();
  png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if(!png) abort();
  png_infop info = png_create_info_struct(png);
  if(!info) abort();
  if(setjmp(png_jmpbuf(png))) abort();
  png_init_io(png, fp);
  png_read_info(png, info);
  width      = png_get_image_width(png, info);
  height     = png_get_image_height(png, info);
  color_type = png_get_color_type(png, info);
  bit_depth  = png_get_bit_depth(png, info);
  printf("width: %d height: %d\n", width, height);

  if(bit_depth == 16)
    png_set_strip_16(png);

  if(color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb(png);

  if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    png_set_expand_gray_1_2_4_to_8(png);

  if(png_get_valid(png, info, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(png);

  if(color_type == PNG_COLOR_TYPE_RGB ||
     color_type == PNG_COLOR_TYPE_GRAY ||
     color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_filler(png, 0xFF, PNG_FILLER_AFTER);

  if(color_type == PNG_COLOR_TYPE_GRAY ||
     color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    png_set_gray_to_rgb(png);

  png_read_update_info(png, info);

  row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
  for(int y = 0; y < height; y++) {
    row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info));
    //printf("%d\n", row_pointers[y]);
  }

  png_read_image(png, row_pointers);

  fclose(fp);
}

void write_png_file(char *filename) {
  int y;

  FILE *fp = fopen(filename, "wb");
  if(!fp) abort();

  png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  if (!png) abort();

  png_infop info = png_create_info_struct(png);
  if (!info) abort();

  if (setjmp(png_jmpbuf(png))) abort();

  png_init_io(png, fp);

  png_set_IHDR(
    png,
    info,
    width, height,
    8,
    PNG_COLOR_TYPE_RGBA,
    PNG_INTERLACE_NONE,
    PNG_COMPRESSION_TYPE_DEFAULT,
    PNG_FILTER_TYPE_DEFAULT
  );

  png_set_expand(png);
  png_write_info(png, info);
  png_write_image(png, row_pointers);
  png_write_end(png, NULL);

  for(int y = 0; y < height; y++) {
    free(row_pointers[y]);
  }
  free(row_pointers);

  fclose(fp);
}

void process_png_file() {


    const int midY = ceil(height/2);
    printf("midY: %d\n", midY);
    int countY = -midY+height;
    printf("countY: %d\n", countY);
    png_byte color[] = {255,255,255};
    png_byte color_white[] = {0,0,0};
  for(int y = 0; y < height; y++) {
    png_bytep row = row_pointers[y];
    //printf("debug proc\n");

    for(int x = 0; x < width; x++) {
      png_bytep px = &(row[x * 4]);
        for(int i = 0; i < 3; ++i){
            if (y == ceil((midY-sin(x*300)))){
                //printf("y: %d ceil: %d\n",y, ceil(sin(x)));
                px[i] = color[i];
            }
            else {
                px[i] = color_white[i];
            }

        }
    }
  }
}

int main(int argc, char *argv[]) {
  if(argc != 3) abort();

  read_png_file(argv[1]);
  process_png_file();

  write_png_file(argv[2]);

  return 0;
}

在 function 進程中,這可能是問題開始的地方:

for(int x = 0; x < width; x++) {
      png_bytep px = &(row[x * 4]);
        for(int i = 0; i < 3; ++i){
            if (y == ceil((midY-sin(x*300)))){ //this part
                //printf("y: %d ceil: %d\n",y, ceil(sin(x)));
                px[i] = color[i];
            }
            else {
                px[i] = color_white[i];
            }

        }
    }

我希望它有更大的幅度。

雖然我希望代碼更短,但它似乎需要像https://github.com/mikolalysenko/lena/blob/master/lena.png這樣的虛擬 png,這就是 png 的大小看起來相同的原因。 您可以刪除 read_png_file() ,因為我們只是在處理寫作內容(我不知道該怎么做,這就是為什么它是復制意大利面)。

sin function 以弧度表示參數。 一個完整的波只有 6.28 弧度(pi 乘以 2)。 由於x是從左側算起的像素數,因此您為每個像素跳過了 300 多個弧度,這意味着您實際上每個像素跳過了 47.75 個完整的波,這看起來與每個像素向后移動 0.25 個波相同。 因此,圖像中的波浪只有 4 個像素寬(每個波浪)。

我建議嘗試每像素 0.1 弧度左右。 這將使波浪大約 62.8 像素寬,因此它們實際上大到可以看到。 sin(x*300)更改為sin(x*0.1)


正弦波中的 Y 值僅 go 介於 -1 和 1 之間。由於您使用 Y 值來確定要繪制的像素,因此波只有 2 個像素高。 我建議您將其乘以 50 左右,以使您的波浪高 100 像素,因此它們實際上大到可以看到。 sin(whatever)更改為sin(whatever)*50

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM