C ve D'de resim dosyası oluşturma

Başlatan Erdem, 08 Ağustos 2012 - 23:49:43

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

Erdem

Daha bügün öğrendiğim hiç bir grafik kütüphanesine ihtiyaç duymadan bir resim dosyası oluşturabileceğiniz bir programın kaynak kodunu paylaşmak istiyorum.

Bu resim dosyası biçimi Netpbm olarak geçiyor ve kolaylıkla bu şekilde bir resim dosyası oluşturabiliyoruz.



Bu arada çemberin kesikli olması sizi şaşırtmasın çünkü bu sadece çember çizme algoritmasının nasıl kullanıldığını gösteren bir örnek. Merak edenler devamını okuyabilir:

https://banu.com/blog/7/drawing-circles/

// cember.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

typedef struct
{
    size_t         genislik;
    size_t         yukseklik;
    unsigned char *veri;
} Resim;

static Resim * yeni_resim (size_t genislik,
                           size_t yukseklik)
{
    Resim *resim;

    resim = malloc (sizeof *resim);
    resim->genislik = genislik;
    resim->yukseklik = yukseklik;
    resim->veri = malloc (genislik * yukseklik);

    return resim;
}

static void bellegi_geri_ver (Resim *resim)
{
    free (resim->veri);
    free (resim);
}

static void resim_doldur (Resim *resim,
                          unsigned char  deger)
{
    memset (resim->veri, deger, resim->genislik * resim->yukseklik);
}


static void resim_piksel_doldur (Resim *resim,
                                 ssize_t        x,
                                 ssize_t        y,
                                 unsigned char  deger)
{
    size_t tx, ty;
    unsigned char *p;

    tx = (resim->genislik / 2) + x;
    ty = (resim->yukseklik / 2) + y;

    p = resim->veri + (ty * resim->genislik) + tx;

    *p = deger;
}

static void resmi_kaydet (const Resim *resim,
                          const char  *dosyaismi)
{
    FILE *dosya;

    dosya = fopen (dosyaismi, "wb");
    if (!dosya)
        return;

    fprintf (dosya, "P5\n");
    fprintf (dosya, "%zu %zu\n", resim->genislik, resim->yukseklik);
    fprintf (dosya, "255\n");

    fwrite (resim->veri, 1, resim->genislik * resim->yukseklik, dosya);

    fclose (dosya);
}

static void cember_ciz (Resim *resim,
                        int yaricap,
                        unsigned char  deger)
{
    int x, y;

    for (x = -yaricap; x <= yaricap; x++) {
        y = (int) sqrt ((double) (yaricap * yaricap) - (x * x));

        resim_piksel_doldur (resim, x, y, deger);
        resim_piksel_doldur (resim, x, -y, deger);
    }
}

int main (int argc, char *argv[])
{
    Resim *resim;

    resim = yeni_resim (600, 600);

    resim_doldur (resim, 0xff);
    cember_ciz (resim, 200, 0);
    resmi_kaydet (resim, "cember.pgm");

    bellegi_geri_ver (resim);

    return 0;
}


C kodunu derlerken gcc cember.c -o cember -lm şeklinde sona lm eklemeniz gerekiyor. Bu da D kodu  ;)


import std.stdio;
import std.algorithm;
import std.math;

struct Resim
{
    size_t         genişlik;
    size_t         yükseklik;
    ubyte[]        veri;

    this(size_t genişlik, size_t yükseklik)
    {
        this.genişlik = genişlik;
        this.yükseklik = yükseklik;
        veri.length = genişlik * yükseklik;
    }

    void doldur(ubyte değer)
    {
        std.algorithm.fill(veri, değer);
    }

    void pikselÇiz(sizediff_t     x,
                   sizediff_t     y,
                   ubyte          değer)
    {
        size_t tx = (genişlik / 2) + x;
        size_t ty = (yükseklik / 2) + y;

        veri[(ty * genişlik) + tx] = değer;
    }

    void kaydet(string dosyaismi)
    {
        auto dosya = File(dosyaismi, "wb");

        dosya.writeln("P5");
        dosya.writefln("%s %s", genişlik, yükseklik);
        dosya.writefln("255");

        dosya.rawWrite(veri);
    }
}

void çemberÇiz (ref Resim      resim,
                  int          yarıçap,
                  ubyte        değer)
{
    foreach (x; -yarıçap .. yarıçap + 1) {
        int y = cast(int)sqrt(cast(double)(yarıçap * yarıçap) - (x * x));

        resim.pikselÇiz(x, y, değer);
        resim.pikselÇiz(x, -y, değer);
    }
}

void main()
{
    auto resim = Resim(600, 600);

    resim.doldur(0xff);
    çemberÇiz(resim, 200, 0);
    resim.kaydet("çember.pgm");
}


D kodunu derlemek için dmd cember.d demeniz yeterli. Bu arada github'a yeni özellikler eklemişler.  Ben de ufak bir kod parçası oluşturdum  :D

https://gist.github.com/3298771
Eğer Arch Linux tabanlı bir dağıtıma geçmek isterseniz Arcolinux D sürümünü buradan indirebilirsiniz.

Elektronik

sem

İlk boş zamanda incelemek lazım...

Teşekkürler.
".NET çemberinden geçen lirisist etkisi bir 'Volcano', bir yüzüm Java bir yüzüm Badalamenti Don Tano"
----------------------------------------------------------------------------------------------------------------------
"Her yer ölüm yine, burası dünya
Derken ölüm bile bu nasıl dünya?
Benden ölüm dile, batıyor gün yine
Burası dünya?