DEV Community

Ilya Siganov
Ilya Siganov

Posted on • Edited on • Originally published at vk.com

ImageMagick эксперименты #4

Пятница, и этим всё сказано. Насладимся же сортировкой изображения. Я написал построчечную сортировку каналов и полную. Некоторые результаты были весьма неожиданными, особенно segmentation fault, иногда :D.

Частичная сортировка.

Начнем с сортировки красного канала. Напомню, что машина желтая. Выглядит как закат. Ну почти.

Сортировка по яркости красного канала

Сортировка по яркости красного канала

А теперь отправим синий канал в другую сторону.

Красный канал сортируется в правую сторону, синий — в левую

Красный канал сортируется в правую сторону, синий — в левую

Картинка всё еще похожа на оригинал. НУЖНО ИСПРАВИТЬ ЭТОТ НЕДОЧЕТ.

Alt Text

Вот это я понимаю искусство. Полная сортировка всех каналов в левую сторону. Поздравляю. Так бы выглядела машина на десятой скорости света.
Мне так понравился эффект растаскивания цветов в разные стороны, что сделал еще несколько экземпляров.

Alt Text

Хорошо, а вот еще одна подопытная няша. Отсортируем её полностью.

Alt Text

УПС. это не то чего я ожидал. Тьфу ты, перепутал сортировку. Часть каналов отсортирована полностью другая часть — нет. Короче я не понял, что тут произошло. Наверное баг в проге.

Alt Text

Вот это другое дело. Полностью отсортированная картинка. Назовем её розовый градиент [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;
}
view raw sort.c hosted with ❤ by GitHub

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Heroku

This site is powered by Heroku

Heroku was created by developers, for developers. Get started today and find out why Heroku has been the platform of choice for brands like DEV for over a decade.

Sign Up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay