Graphics (计算机图形学)径向图像失真

Graphics (计算机图形学)径向图像失真,graphics,bitmap,effect,Graphics,Bitmap,Effect,我需要创建一种效果,通过径向拉伸或收缩位图的“像素层”(如图所示),从而径向扭曲位图: 通过彩色圆圈(其厚度)显示应用于图像的变换 我应该采取什么方法?我有一个位图(像素数组)和另一个位图,这应该是应用这种过滤器的结果(因此,位图上应该有某种圆形水波)。 我在哪里能读到关于创造这种效果的书? 谢谢。看看这里 缩放和旋转模糊 它是Java,但它可能适合您的要求。好吧,最准确的结果来自将欧几里德坐标映射到极坐标矩阵。然后你就可以很容易地把它们伸出来。然后将它们转换回欧几里德表示法并保存。我将在一

我需要创建一种效果,通过径向拉伸或收缩位图的“像素层”(如图所示),从而径向扭曲位图:

通过彩色圆圈(其厚度)显示应用于图像的变换

我应该采取什么方法?我有一个位图(像素数组)和另一个位图,这应该是应用这种过滤器的结果(因此,位图上应该有某种圆形水波)。 我在哪里能读到关于创造这种效果的书? 谢谢。

看看这里

缩放和旋转模糊


它是Java,但它可能适合您的要求。

好吧,最准确的结果来自将欧几里德坐标映射到极坐标矩阵。然后你就可以很容易地把它们伸出来。然后将它们转换回欧几里德表示法并保存。我将在一秒钟内编写和编辑一些代码

好吧,我有点激动,但这是我的代码。它将获取位图,将其转换为极坐标,并将其保存。现在,基于径向的失真应该是轻而易举的事了

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define PI 3.141592654

#define C_R 1000
#define C_S 1000
#define C_M 2000

typedef struct{ int r,g,b; } color;
typedef struct{ int t; color* data; int w, h; } bitmap;
typedef struct{ int t; color* data; int r, s, w, h; } r_bitmap;

bitmap* bmp_load_from_file( const char* fname ){
    FILE* b = fopen( fname, "rb" );
    if( b <= 0 ) return 0;
    int num;
    fscanf( b, "BM%n", &num );
    if( num < 2 ) return 0;
    struct{ int size, reserved, offset;
        int hsize, wid, hig, planes:16, bpp:16, comp, bmpsize, hres, vres, colors, important; } head;
    fread( &head, 13, 4, b );
    bitmap* bmp = malloc( sizeof( bitmap ) );
    bmp->data = malloc( head.wid * head.hig * sizeof( color ) );
    bmp->w = head.wid;
    bmp->h = head.hig;
    for( int y = head.hig - 1; y >= 0; --y ){
        int x;
        for( x = 0; x < head.wid; ++x ){
            color t;
            t.r = fgetc( b );
            t.g = fgetc( b );
            t.b = fgetc( b );
            bmp->data[x+y*bmp->w] = t;
        }
        x*=3;
        while( x%4 != 0 ){
            ++x;
            fgetc( b );
        }
    }
    bmp->t = 0;
    fclose( b );
    return bmp;
}

void bmp_save( const char* fname, bitmap* bmp ){
    FILE* b = fopen( fname, "wb" );
    if( b <= 0 ) return 0;
    struct{ int size, reserved, offset;
        int hsize, wid, hig, planes:16, bpp:16, comp, bmpsize, hres, vres, colors, important; } head;
    fprintf( b, "BM" );
    head.size = 3 * (bmp->w+4)/4*4 * bmp->h + 54;
    head.offset = 54;
    head.hsize = 40;
    head.wid = bmp->w;
    head.hig = bmp->h;
    head.planes = 1;
    head.bpp = 24;
    head.comp = 0;
    head.bmpsize = 3 * (bmp->w+4)/4*4 * bmp->h;
    head.hres = 72;
    head.vres = 72;
    head.colors = 0;
    head.important = 0;
    fwrite( &head, 13, 4, b );
    for( int y = bmp->h - 1; y >= 0; --y ){
        int x;
        for( x = 0; x < bmp->w; ++x ){
            fputc( bmp->data[x + y * bmp->w].r, b );
            fputc( bmp->data[x + y * bmp->w].g, b );
            fputc( bmp->data[x + y * bmp->w].b, b );
        }
        x*=3;
        while( x % 4 != 0 ){
            ++x;
            fputc(0, b);
        }
    }
    fclose( b );
}

color color_mix( color a, color b, int offset ){ /*offset is a value between 0 and 255 to determine the weight. the lower it is the more color a gets*/
    //if( offset > 255 || offset < 0)
        //printf("%i\t", offset);
    a.r += ( b.r - a.r ) * offset / 255;
    a.g += ( b.g - a.g ) * offset / 255;
    a.b += ( b.b - a.b ) * offset / 255;
    return a;
}

r_bitmap* bmp_to_r( bitmap* b ){
    r_bitmap* r = malloc( sizeof( r_bitmap ) );
    r->t = 1;
    int radius = sqrt( b->w * b->w + b->h * b->h ) / 2 * C_R / C_M + 2;
    int step = C_S * ( b->w + b->h ) / C_M;
    r->data = malloc( radius * step * sizeof( color ) );
    r->r = radius;
    r->s = step;
    r->w = b->w;
    r->h = b->h;
    color black = {0, 0, 0};
    for( double i = 0; i < radius; ++ i ){
        for( double j = 0; j < step; ++j ){
            double x = i * C_M * cos( 2 * PI * j / step ) / C_R + b->w / 2;
            double y = i * C_M * sin( 2 * PI * j / step ) / C_R + b->h / 2;
            int ix = x;
            int iy = y;
            if( x < 0 || x >= b->w || y < 0 || y >= b->h )
                r->data[(int)(j + i * step)] = black;
            else{
                color tmp = b->data[ix + iy * b->w];
                if( iy < b->h - 1 ){
                    int off = 255 * (y - iy);
                    tmp = color_mix( tmp, b->data[ix + (iy+1) * b->w], off );
                }
                if( ix < b->w - 1 ){
                    int off = 255 * ( x - ix );
                    tmp = color_mix( tmp, b->data[ix +1 + iy * b->w], off );
                }
                r->data[(int)(j + i * step)] = tmp;
            }
        }
    }
    return r;
}

bitmap* bmp_from_r( r_bitmap* r ){
    bitmap* b = malloc( sizeof( bitmap ) );
    b->t = 0;
    b->data = malloc( r->w * r->h * sizeof( color ) );
    b->w = r->w;
    b->h = r->h;
    for( int y = 0; y < b->h; ++y ){
        for( int x = 0; x < b->w; ++x ){
            int tx = x - b->w/2;
            int ty = y - b->h/2;

            double rad = sqrt( tx*tx+ty*ty ) * C_R / C_M;
            double s = atan2( ty, tx );
            if( s < 0 ) s += 2 * PI;
            s *= r->s / ( 2 * PI );

            int is = s;
            int irad = rad;

            color tmp = r->data[(int)(is + irad * r->s)];
            /*if( x > 0 && x < r->w - 1 && y > 0 && y < r->h - 1 ){
                tmp = color_mix(tmp, r->data[((int)(is+1)%r->s + irad * r->s)], abs(255* rad - floor(rad)));
                tmp = color_mix(tmp, r->data[(is + (irad + 1) * r->s)], abs(255* s - floor(s)));
            }*/
            b->data[x+y*b->w] = tmp;
        }
    }
    return b;
}



int main( ) {
    bitmap* b = bmp_load_from_file( "foo.bmp" );
    r_bitmap* r = bmp_to_r( b );
    bitmap* c = bmp_from_r( r );
    bmp_save( "lol.bmp", c );

}
#包括
#包括
#包括
#包括
#定义PI 3.141592654
#定义C_R 1000
#定义C_S 1000
#定义C_M 2000
typedef结构{intr,g,b;}颜色;
typedef结构{intt;color*数据;intw,h;}位图;
typedef结构{intt;color*数据;intr,s,w,h;}r_位图;
位图*bmp\u从\u文件加载\u(常量字符*fname){
文件*b=fopen(fname,“rb”);
如果(b数据=malloc(head.wid*head.hig*sizeof(颜色));
bmp->w=head.wid;
bmp->h=头高;
对于(int y=head.hig-1;y>=0;--y){
int x;
对于(x=0;xdata[x+y*bmp->w]=t;
}
x*=3;
而(x%4!=0){
++x;
fgetc(b);
}
}
bmp->t=0;
fclose(b);
返回bmp;
}
无效bmp_保存(常量字符*fname,位图*bmp){
文件*b=fopen(fname,“wb”);
如果(bw+4)/4*4*bmp->h+54;
水头偏移=54;
head.hsize=40;
head.wid=bmp->w;
head.hig=bmp->h;
head.planes=1;
head.bpp=24;
head.comp=0;
head.bmpsize=3*(bmp->w+4)/4*4*bmp->h;
head.hres=72;
head.vres=72;
head.colors=0;
head.important=0;
fwrite(和head,13,4,b);
对于(int y=bmp->h-1;y>=0;--y){
int x;
对于(x=0;xw;++x){
fputc(bmp->data[x+y*bmp->w].r,b);
fputc(bmp->data[x+y*bmp->w].g,b);
fputc(bmp->data[x+y*bmp->w].b,b);
}
x*=3;
而(x%4!=0){
++x;
fputc(0,b);
}
}
fclose(b);
}
color color_mix(color a,color b,int offset){/*offset是一个介于0和255之间的值,用于确定权重。它越低,a得到的颜色越多*/
//如果(偏移量>255 | |偏移量<0)
//printf(“%i\t”,偏移量);
a、 r+=(b.r-a.r)*偏移量/255;
a、 g+=(b.g-a.g)*偏移量/255;
a、 b+=(b.b-a.b)*偏移量/255;
返回a;
}
r_位图*bmp_到r(位图*b){
r_位图*r=malloc(sizeof(r_位图));
r->t=1;
int radius=sqrt(b->w*b->w+b->h*b->h)/2*C\u R/C\u M+2;
int step=C_S*(b->w+b->h)/C_M;
r->data=malloc(半径*步长*大小(颜色));
r->r=半径;
r->s=步进;
r->w=b->w;
r->h=b->h;
黑色={0,0,0};
对于(双i=0;iw/2;
双y=i*C_M*sin(2*PI*j/步)/C_R+b->h/2;
int ix=x;
int-iy=y;
如果(x<0 | x>=b->w | y<0 | y>=b->h)
r->data[(int)(j+i*步进)]=黑色;
否则{
颜色tmp=b->数据[ix+iy*b->w];
如果(iyh-1){
int off=255*(y-iy);
tmp=颜色混合(tmp,b->data[ix+(iy+1)*b->w],关闭);
}
如果(ixw-1){
int off=255*(x-ix);
tmp=颜色混合(tmp,b->data[ix+1+iy*b->w],关闭);
}
r->data[(int)(j+i*step)]=tmp;
}
}
}
返回r;
}
位图*bmp\u from\u r(r\u位图*r){
位图*b=malloc(sizeof(位图));
b->t=0;
b->data=malloc(r->w*r->h*sizeof(颜色));
b->w=r->w;
b->h=r->h;
对于(int y=0;yh;++y){
对于(int x=0;xw;++x){
int tx=x-b->w/2;
int ty=y-b->h/2;
双rad=sqrt(tx*tx+ty*ty)*C\u R/C\M;
双s=atan2(ty,tx);
如果(s<0)s+=2*PI;
s*=r->s/(2*PI);
int is=s;
int irad=rad;
颜色tmp=r->data[(int)(is+irad*r->s)];
/*如果(x>0&&xw-1&&y>0&&yh-1){
tmp=color_mix(tmp,r->data[((int)(is+1)%r->s+irad*r->s)],abs(255*rad-地板(rad));
tmp=颜色混合(tmp,r->data[(is+(irad+1)*r->s)],abs(255*s-地板);
}*/
b->数据[x+y*b->w]=tmp;
}
}
返回b;
}
int main(){
位图*b=bmp_从_文件(“foo.bmp”)加载_;
r_位图*r=bmp_到r(b);
位图*c=bmp\u from\u r(r);
bmp_保存(“lol.bmp”,c);
}

谢谢,但我不是在模糊,而是在寻找径向拉伸失真效果。。