【问题标题】:(computer graphics) radial image distortion(计算机图形学)径向图像失真
【发布时间】:2012-03-27 09:41:15
【问题描述】:

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

http://i.stack.imgur.com/V6Voo.png

通过彩色圆圈(它们的粗细)显示应用到图像的变换

我应该采取什么方法?我有一个位图(像素数组)和另一个位图,这应该是应用这种过滤器的结果(因此,位图上应该有某种圆形水波纹)。 我在哪里可以阅读有关创建此类效果的信息? 谢谢。

【问题讨论】:

    标签: graphics bitmap effect


    【解决方案1】:

    试试看这里

    http://www.jhlabs.com/ip/blurring.html

    缩放和旋转模糊

    它是 Java,但它仍然可以满足您的要求。

    【讨论】:

    • 谢谢,但不是模糊,我正在寻找径向拉伸失真效果..
    【解决方案2】:

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

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

    #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 );
    
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      相关资源
      最近更新 更多