Пятница, и этим всё сказано. Насладимся же сортировкой изображения. Я написал построчечную сортировку каналов и полную. Некоторые результаты были весьма неожиданными, особенно segmentation fault, иногда :D.
Частичная сортировка.
Начнем с сортировки красного канала. Напомню, что машина желтая. Выглядит как закат. Ну почти.
А теперь отправим синий канал в другую сторону.
Картинка всё еще похожа на оригинал. НУЖНО ИСПРАВИТЬ ЭТОТ НЕДОЧЕТ.
Вот это я понимаю искусство. Полная сортировка всех каналов в левую сторону. Поздравляю. Так бы выглядела машина на десятой скорости света.
Мне так понравился эффект растаскивания цветов в разные стороны, что сделал еще несколько экземпляров.
Хорошо, а вот еще одна подопытная няша. Отсортируем её полностью.
УПС. это не то чего я ожидал. Тьфу ты, перепутал сортировку. Часть каналов отсортирована полностью другая часть — нет. Короче я не понял, что тут произошло. Наверное баг в проге.
Вот это другое дело. Полностью отсортированная картинка. Назовем её розовый градиент [s]Малевича[/s].
Это всё. В следующем выпуске я покажу как один пиксель может “сломать” всю картинку.
Исходники
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <wand/MagickWand.h> | |
#include <sys/types.h> | |
//gcc `MagickWand-config --cflags --cppflags` -o main main.c `MagickWand-config --ldflags --libs` | |
static int cmp_quant(const void *p1, const void *p2){ | |
return *(Quantum *)p1 >= *(Quantum *)p2; | |
} | |
static int reverse_cmp_quant(const void *p1, const void *p2){ | |
return *(Quantum *)p1 < *(Quantum *)p2; | |
} | |
void full_sort(char const *sours, char const *res){ | |
MagickWand *mw_1,*mw_res; | |
PixelIterator *imw_1,*imw_res; | |
PixelWand **pmw_1,**pmw_res; | |
Quantum *qr_1,*qg_1,*qb_1; | |
unsigned long y; | |
register long x; | |
unsigned int width,height; | |
MagickWandGenesis(); | |
mw_1 = NewMagickWand(); | |
MagickReadImage(mw_1, sours); | |
width = MagickGetImageWidth(mw_1); | |
height = MagickGetImageHeight(mw_1); | |
printf("FULL Sort img\nwidth %d\nheight %d\n",width,height); | |
mw_res = NewMagickWand(); | |
MagickSetSize(mw_res,width,height); | |
MagickReadImage(mw_res,"xc:none"); | |
imw_1 = NewPixelIterator(mw_1); | |
imw_res = NewPixelIterator(mw_res); | |
long int hw = height*width; | |
qr_1 = (Quantum*)malloc(hw*sizeof(Quantum)); | |
qb_1 = (Quantum*)malloc(hw*sizeof(Quantum)); | |
qg_1 = (Quantum*)malloc(hw*sizeof(Quantum)); | |
for(y = 0;y < height; ++y){ | |
pmw_1 = PixelGetNextIteratorRow(imw_1, &width); | |
for (x = 0;x < (long)width; ++x){ | |
qr_1[x+y*width] = PixelGetRedQuantum(pmw_1[x]); | |
qg_1[x+y*width] = PixelGetGreenQuantum(pmw_1[x]); | |
qb_1[x+y*width] = PixelGetBlueQuantum(pmw_1[x]); | |
} | |
} | |
qsort(qr_1,width*height,sizeof(Quantum),cmp_quant); | |
qsort(qb_1,width*height,sizeof(Quantum),reverse_cmp_quant); | |
// qsort(qg_1,width*height,sizeof(Quantum),cmp_quant); | |
for (y = 0;y < height; ++y){ | |
pmw_res = PixelGetNextIteratorRow(imw_res, &width); | |
for (x = 0;x < (long)width; ++x){ | |
PixelSetRedQuantum(pmw_res[x], qr_1[x+y*width] ); | |
PixelSetGreenQuantum(pmw_res[x], qg_1[x+y*width] ); | |
PixelSetBlueQuantum(pmw_res[x], qb_1[x+y*width] ); | |
} | |
PixelSyncIterator(imw_res); | |
} | |
MagickWriteImage(mw_res,res); | |
imw_1 = DestroyPixelIterator(imw_1); | |
mw_1 = DestroyMagickWand(mw_1); | |
imw_res = DestroyPixelIterator(imw_res); | |
mw_res = DestroyMagickWand(mw_res); | |
free(qr_1); | |
free(qb_1); | |
free(qg_1); | |
MagickWandTerminus(); | |
} | |
void sort(char const *sours, char const *res){ | |
MagickWand *mw_1,*mw_res; | |
PixelIterator *imw_1,*imw_res; | |
PixelWand **pmw_1,**pmw_res; | |
Quantum *qr_1,*qg_1,*qb_1; | |
unsigned long y; | |
register long x; | |
unsigned int width,height; | |
MagickWandGenesis(); | |
mw_1 = NewMagickWand(); | |
MagickReadImage(mw_1, sours); | |
width = MagickGetImageWidth(mw_1); | |
height = MagickGetImageHeight(mw_1); | |
printf("Sort rows img\nwidth %d\nheight %d\n",width,height); | |
mw_res = NewMagickWand(); | |
MagickSetSize(mw_res,width,height); | |
MagickReadImage(mw_res,"xc:none"); | |
imw_1 = NewPixelIterator(mw_1); | |
imw_res = NewPixelIterator(mw_res); | |
qr_1 = (Quantum*)malloc(width*sizeof(Quantum)); | |
qb_1 = (Quantum*)malloc(width*sizeof(Quantum)); | |
qg_1 = (Quantum*)malloc(width*sizeof(Quantum)); | |
for(y = 0;y < height; ++y){ | |
pmw_1 = PixelGetNextIteratorRow(imw_1, &width); | |
pmw_res = PixelGetNextIteratorRow(imw_res, &width); | |
for (x = 0;x < (long)width; ++x){ | |
qr_1[x] = PixelGetRedQuantum(pmw_1[x]); | |
qg_1[x] = PixelGetGreenQuantum(pmw_1[x]); | |
qb_1[x] = PixelGetBlueQuantum(pmw_1[x]); | |
} | |
qsort(qr_1,width,sizeof(Quantum),cmp_quant); | |
qsort(qb_1,width,sizeof(Quantum),reverse_cmp_quant); | |
// qsort(qg_1,width,sizeof(Quantum),cmp_quant); | |
for (x = 0;x < (long)width; ++x){ | |
PixelSetRedQuantum(pmw_res[x], qr_1[x] ); | |
PixelSetGreenQuantum(pmw_res[x], qg_1[x] ); | |
PixelSetBlueQuantum(pmw_res[x], qb_1[x] ); | |
} | |
PixelSyncIterator(imw_res); | |
} | |
MagickWriteImage(mw_res,res); | |
imw_1 = DestroyPixelIterator(imw_1); | |
mw_1 = DestroyMagickWand(mw_1); | |
imw_res = DestroyPixelIterator(imw_res); | |
mw_res = DestroyMagickWand(mw_res); | |
free(qr_1); | |
free(qb_1); | |
free(qg_1); | |
MagickWandTerminus(); | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
srand(time(NULL)); | |
full_sort(argv[1],argv[2]); | |
sort(argv[1],argv[2]); | |
return 0; | |
} |
Top comments (0)