⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vectorize.c

📁 就是将BMP文件转换为DXF格式的文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  Ras2Vec by Davide Libenzi ( Raster to vector conversion program )
 *  Copyright (C) 1999  Davide Libenzi
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Davide Libenzi <davidel@maticad.it>
 *
 */


#include<windows.h>
#include<windowsx.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#include<float.h>
#include<limits.h>
#include"ras2vec.h"
#include"dbll_list.h"
#include"himage.h"
#include"thinner.h"
#include"vectorize.h"
#include"filescan.h"
#include"flushpoly.h"
#include"tree.h"
#include"log.h"
#include"util.h"


#define NUM_DIRECTIONS              8
#define MAX_SEARCH_DIRS             (NUM_DIRECTIONS-1)


typedef struct vect_poly_record
{
    link_list_hdr  *p_poly_list;
    img_point       prev_pnt,
                    last_pnt,
                    pnt;
}               vect_poly;


static int      cmp_img_points(img_point * p_imgp1, img_point * p_imgp2);
static HTREE    get_points_tree(link_list_hdr * p_pnts_list);
static int      do_vectorize(bw_bmp_header * p_bmph, BYTE * p_img_mem, int back_ground,
                        FILE * fp_poly, double pnt_error_tollerance,
                        double min_polyline_lenght, HTREE node_pnts_htree,
                        link_list_hdr * p_node_pnts_list);
static int      trace_point(bw_bmp_header * p_bmph, BYTE * p_img_mem, int back_ground,
                        FILE * fp_poly, double pnt_error_tollerance,
                        double min_polyline_lenght, int curr_direction,
                        HTREE node_pnts_htree, vect_poly * p_vect_poly,
                        img_point * p_imgp, int *p_poly_flushed_flag);
static int      find_start_point(bw_bmp_header * p_bmph, BYTE * p_img_mem, int back_ground,
                        int yy_start, img_point * p_imgp);
static void     get_next_point(img_point * p_start_imgp, int direction,
                        img_point * p_imgp);
static vect_poly *create_vect_poly(img_point * p_imgp);
static void     free_vect_poly(vect_poly * p_vect_poly);
static int      add_vect_poly_point(vect_poly * p_vect_poly, img_point * p_imgp);
static int      get_img_pixel(BYTE * p_img_mem, int back_ground, int xx, int yy);
static void     clear_img_pixel(BYTE * p_img_mem, int back_ground, int xx, int yy);
static void     set_img_pixel(BYTE * p_img_mem, int back_ground, int xx, int yy);


static img_point dirs[] = {{0, 1},
{1, 0},
{0, -1},
{-1, 0},
{1, 1},
{1, -1},
{-1, -1},
{-1, 1},
};
static int      search_dirs[NUM_DIRECTIONS + 1][NUM_DIRECTIONS] =
{
    {0, 4, 7, 1, 3, 5, 6, 2},
    {1, 5, 4, 2, 0, 6, 7, 3},
    {2, 6, 5, 3, 1, 7, 4, 0},
    {3, 7, 6, 0, 2, 4, 5, 1},
    {1, 0, 4, 5, 7, 2, 3, 6},
    {2, 1, 5, 6, 4, 3, 0, 7},
    {3, 2, 6, 7, 5, 0, 1, 4},
    {0, 3, 7, 4, 6, 1, 2, 5},
    {0, 1, 2, 3, 4, 5, 6, 7}
};



/* OK */
int LIB_PROC    cntline_convert_file(char *img_file_name, int use_a_copy,
                        char *poly_file_name, double pnt_error_tollerance,
                        double poly_lenght_factor)
{

    int             passes,
                    back_ground,
                    number_of_polylines;
    HTREE           node_pnts_htree;
    double          min_polyline_lenght = 1.0;
    BYTE           *p_img_mem;
    link_list_hdr  *p_node_pnts_list;
    FILE           *fp_poly;
    img_data        imgd;
    bw_bmp_header   bmph;
    char            temp_img_file_name[MAX_PATH];

    if (use_a_copy)
    {
        char            temp_path[MAX_PATH];

        GetTempPath(sizeof(temp_path), temp_path);
        GetTempFileName(temp_path, "img", 0, temp_img_file_name);
        if (!CopyFile(img_file_name, temp_img_file_name, FALSE))
            return (FALSE);
        img_file_name = temp_img_file_name;
    }
    if ((p_img_mem = (BYTE *) get_image(img_file_name, IMAGE_OPEN_READWRITE,
                            &imgd)) == NULL)
    {
        if (use_a_copy)
            remove(temp_img_file_name);
        return (FALSE);
    }
    bmph = *((bw_bmp_header *) p_img_mem);
    log_printf("- processing image file %s ( %lu bytes )\n", img_file_name,
            (unsigned long) bmph.bih.biHeight * (unsigned long) get_line_size(bmph.bih.biWidth));
    if ((passes = thin_image(p_img_mem, &back_ground)) < 0)
    {
        free_image(&imgd);
        if (use_a_copy)
            remove(temp_img_file_name);
        return (FALSE);
    }
    min_polyline_lenght = (poly_lenght_factor > 0.0) ?
            (((double) max(bmph.bih.biWidth, bmph.bih.biHeight)) / poly_lenght_factor) : 1.0;
    log_printf("- retrieving node points\n");
    if ((p_node_pnts_list = get_node_points(&bmph, p_img_mem, back_ground)) == NULL)
    {
        free_image(&imgd);
        if (use_a_copy)
            remove(temp_img_file_name);
        return (FALSE);
    }
    log_printf("- found %d node points\n", ll_get_list_count(p_node_pnts_list));
    if ((node_pnts_htree = get_points_tree(p_node_pnts_list)) == NULL)
    {
        ll_empty_free_list(p_node_pnts_list);
        free_image(&imgd);
        if (use_a_copy)
            remove(temp_img_file_name);
        return (FALSE);
    }
    if ((fp_poly = fopen(poly_file_name, "wt")) == NULL)
    {
        tree_empty(node_pnts_htree);
        ll_empty_free_list(p_node_pnts_list);
        free_image(&imgd);
        if (use_a_copy)
            remove(temp_img_file_name);
        return (FALSE);
    }
    log_printf("- begin raster to vector conversion to file %s\n", poly_file_name);
    if ((number_of_polylines = do_vectorize(&bmph, p_img_mem, back_ground, fp_poly,
                            pnt_error_tollerance, min_polyline_lenght, node_pnts_htree, p_node_pnts_list)) < 0)
    {
        tree_empty(node_pnts_htree);
        ll_empty_free_list(p_node_pnts_list);
        fclose(fp_poly);
        free_image(&imgd);
        if (use_a_copy)
            remove(temp_img_file_name);
        return (FALSE);
    }
    log_printf("- generated %d polylines in file %s\n", number_of_polylines,
            poly_file_name);
    ll_empty_free_list(p_node_pnts_list);
    tree_empty(node_pnts_htree);
    fclose(fp_poly);
    free_image(&imgd);
    if (use_a_copy)
        remove(temp_img_file_name);
    return (TRUE);

}


/* OK */
static int      cmp_img_points(img_point * p_imgp1, img_point * p_imgp2)
{

    if (p_imgp1->y > p_imgp2->y)
        return (+1);
    if (p_imgp1->y < p_imgp2->y)
        return (-1);
    if (p_imgp1->x > p_imgp2->x)
        return (+1);
    if (p_imgp1->x < p_imgp2->x)
        return (-1);
    return (0);

}


/* OK */
static HTREE    get_points_tree(link_list_hdr * p_pnts_list)
{

    int             index = 0;
    HTREE           htree;
    img_point       min_img_point = {INT_MIN, INT_MIN};

    if ((htree = tree_create(sizeof(img_point), &min_img_point,
                            (int (*) (void *, void *)) cmp_img_points)) == NULL)
        return (NULL);
    ll_set_list_currpntr(p_pnts_list, TG_HEAD);
    do
    {
        img_point       pnt;

        if (!ll_get_list_user_data(p_pnts_list, &pnt))
            break;
        if (!tree_insert(htree, &pnt, (void *) (index + 1)))
        {
            tree_empty(htree);
            return (NULL);
        }
        ++index;
    } while (ll_set_list_currpntr(p_pnts_list, TG_AFTER) == TG_AFTER);
    return (htree);

}


/* OK */
static int      do_vectorize(bw_bmp_header * p_bmph, BYTE * p_img_mem, int back_ground,
                        FILE * fp_poly, double pnt_error_tollerance,
                        double min_polyline_lenght, HTREE node_pnts_htree,
                        link_list_hdr * p_node_pnts_list)
{

    int             number_of_polylines = 0,
                    current_line = 0,
                    polyline_flushed;
    vect_poly      *p_vect_poly;
    img_point       pnt,
                    next_pnt;

    ll_set_list_currpntr(p_node_pnts_list, TG_HEAD);
    do
    {
        int             direction;

        if (!ll_get_list_user_data(p_node_pnts_list, &pnt))
            break;
        for (direction = 0; direction < NUM_DIRECTIONS; direction++)
        {
            get_next_point(&pnt, direction, &next_pnt);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -