• 基于标准C语言的数字图像处理基本框架


    考虑到现有的数字图像处理都是基于Windows平台,都或多或少使用了Win32 API函数,不能移植到Linux或者嵌入式系统中。为了使程序可移植,采用标准C语言建立了数字图像处理的基本框架,如下图所示:

    uml

    程序参考了网上一些博客的内容,并进行了改变,建立了符合自己习惯的数据结构。主要实现了bmp格式图像的打开、保存、创建、图像颜色空间转换等功能,暂时还没有添加具体的处理函数。我想,既然有了程序的框架,添加算法只是编写一个个函数的问题。

    本程序具体实现的功能如下:

    * 打开和保存bmp文件,这里使用自定义数据结构Bitmap,相关函数定义如下:
        bmp.h:
            int CreateBitmap(Bitmap* bmp, int width, int height, int bitCount);
            void ReleaseBitmap(Bitmap* bmp);
            int CheckPath(char *path);
            int ReadBitmap(char* path, Bitmap* bmp);
            int SaveBitmap(char* path, Bitmap* bmp);

    * 图像格式转换
        basicprocess.h:
            int RGB2Gray(Bitmap* src, Bitmap* dst);
            int Gray2RGB(Bitmap* src, Bitmap* dst);
            int Gray2BW(Bitmap* src, Bitmap* dst, int threshold);
            void hsv2rgb(float H, float S, float V, float *R, float *G, float *B);
            void rgb2hsv(float R, float G, float B, float *H, float *S, float* V);

    程序源码如下,欢迎大家批评指正。

      1/*
      2****************************************Copyright (c)**************************************************
      3**                                           Feisky
      4**                              http://www.cnblogs.com/feisky/
      5**
      6**------------------------------------- File Info ------------------------------------------------------
      7** File name:           bmp.h
      8** Last modified Date:  2009-9-25
      9** Last Version:        1.0
     10** Descriptions:        位图文件结构及基本函数定义  打开和保存bmp文件
     11**
     12** Created by:          Feisky
     13** Created date:        2009-07-25
     14** Version:             1.0
     15** Descriptions:        Preliminary version.
     16**
     17**------------------------------------------------------------------------------------------------------
     18*/

     19#ifndef BMP_H_INCLUDED
     20#define BMP_H_INCLUDED
     21
     22#include <ctype.h>
     23#include <stdio.h>
     24#include <stdlib.h>
     25#include <malloc.h>
     26#include <string.h>
     27
     28/**
     29 * 位图文件结构及基本函数定义  打开和保存bmp文件
     30 */

     31typedef unsigned short WORD;
     32typedef unsigned long DWORD;
     33typedef long LONG;
     34typedef unsigned char BYTE;
     35
     36/* 位图文件头结构 14字节 */
     37typedef struct tagBITMAPFILEHEADER {
     38    WORD bfType;
     39    DWORD bfSize;
     40    WORD bfReserved1;
     41    WORD bfReserved2;
     42    DWORD bfOffBits;
     43}
     BITMAPFILEHEADER;
     44
     45/* 位图信息头结构 40字节 */
     46typedef struct tagBITMAPINFOHEADER {
     47    DWORD biSize; // 结构长度 40B
     48    LONG biWidth;
     49    LONG biHeight;
     50    WORD biPlanes; // 1
     51    WORD biBitCount; // 表示颜色要用到的位数
     52    DWORD biCompression; // 压缩格式
     53    DWORD biSizeImage; // 位图占用字节数=biWidth'(4的整倍数)*biHeight
     54    LONG biXPelsPerMeter; // 水平分辨率
     55    LONG biYPelsPerMeter; // 垂直分辨率
     56    DWORD biClrUsed; // 本图像用到的颜色数
     57    DWORD biClrImportant; // 本图像的重要颜色数
     58}
     BITMAPINFOHEADER;
     59
     60/* 调色板 4字节 */
     61typedef struct tagRGBQUAD {
     62    BYTE rgbBlue;
     63    BYTE rgbGreen;
     64    BYTE rgbRed;
     65    BYTE rgbReserved;
     66}
     RGBQUAD;
     67
     68/* 定义图像信息 */
     69typedef struct tagBITMAPINFO {
     70    BITMAPINFOHEADER bmiHeader;
     71    RGBQUAD bmiColors[1];
     72}
     BITMAPINFO;
     73
     74/* 定义位图图像 */
     75typedef struct _Bitmap
     76{
     77    BITMAPFILEHEADER bmfh;
     78    BITMAPINFOHEADER bmih;
     79    int width;
     80    int height;
     81    int bitCount;    // 8 或者24
     82    int imageSize;    // 图像数据大小(imageSize=height*widthStep)字节
     83    BYTE* imageData;//排列的图像数据
     84    int widthStep;    //排列的图像行大小
     85}
    Bitmap;
     86
     87/**
     88 * 位图创建函数  创建一个Bitmap结构,并为图像数据分配空间
     89 *
     90 * 使用方法:
     91 *     Bitmap *bmp=(Bitmap*)malloc(sizeof(Bitmap));
     92 *     ret=CreateBitmap(bmp,50,50,3);
     93 */

     94int CreateBitmap(Bitmap* bmp, int width, int height, int bitCount)
     95{
     96    bmp->width=width;
     97    bmp->height=height;
     98    bmp->bmih.biWidth=width;
     99    bmp->bmih.biHeight=height;
    100
    101    bmp->widthStep=(int)((width*bitCount+31)/32)*4;        //计算排列的宽度
    102    bmp->imageSize=bmp->height*bmp->widthStep*sizeof(BYTE);//计算排列的图像大小
    103
    104    if(bitCount==8)
    105    {
    106        bmp->bitCount=8;
    107        bmp->bmfh.bfType=0x4d42;    //注意是4d42 这个地方折磨我一下午啊
    108        bmp->bmfh.bfReserved1=0;
    109        bmp->bmfh.bfReserved2=0;
    110        bmp->bmih.biBitCount=8;
    111        bmp->bmih.biSize=40;
    112        bmp->bmih.biPlanes=1;
    113        bmp->bmfh.bfSize=54+256*4+height*bmp->widthStep;
    114        bmp->bmfh.bfOffBits=1078;
    115        bmp->bmih.biBitCount=8;
    116        bmp->bmih.biCompression=0;
    117        bmp->bmih.biSizeImage=bmp->imageSize;
    118        bmp->bmih.biClrUsed=0;
    119        bmp->bmih.biClrImportant=0;
    120        bmp->bmih.biXPelsPerMeter=0;
    121        bmp->bmih.biYPelsPerMeter=0;
    122    }

    123    else if (bitCount==24)
    124    {
    125        bmp->bitCount=24;
    126        bmp->bmfh.bfType=0x4d42;
    127        bmp->bmih.biBitCount=24;
    128        bmp->bmfh.bfReserved1=0;
    129        bmp->bmfh.bfReserved2=0;
    130        bmp->bmih.biSize=40;
    131        bmp->bmih.biPlanes=1;
    132        bmp->bmfh.bfSize=54+height*bmp->widthStep;
    133        bmp->bmfh.bfOffBits=54;
    134        bmp->bmih.biBitCount=24;
    135        bmp->bmih.biSizeImage=bmp->imageSize;
    136        bmp->bmih.biClrUsed=0;
    137        bmp->bmih.biCompression=0;
    138        bmp->bmih.biClrImportant=0;
    139        bmp->bmih.biXPelsPerMeter=0;
    140        bmp->bmih.biYPelsPerMeter=0;
    141    }

    142    else
    143    {
    144        printf("Error(CreateBitmap): only supported 8 or 24 bits bitmap.\n");
    145        return -1;
    146    }

    147
    148    bmp->imageData=(BYTE*)malloc(bmp->imageSize);        //分配数据空间
    149    if(!(bmp->imageData))
    150    {
    151        printf("Error(CreateBitmap): can not allocate bitmap memory.\n");
    152        return -1;
    153    }

    154    return 0;
    155}

    156
    157/**
    158 * 位图指针释放函数  释放位图数据空间
    159 *
    160 * 使用方法:
    161 *     ReleaseBitmap(bmp);
    162 */

    163void ReleaseBitmap(Bitmap* bmp)
    164{
    165    free(bmp->imageData);
    166    bmp->imageData=NULL;
    167    free(bmp);
    168    bmp=NULL;
    169}

    170
    171/**
    172 * 路径检查函数:是否为BMP文件,是否可读
    173 * 正确返回0,错误返回-1
    174 *
    175 * 使用方法
    176 *         ret=CheckPath(path);
    177 */

    178int CheckPath(char *path)
    179{
    180    FILE *fd;
    181    int len = strlen(path) / sizeof(char);
    182    char ext[3];
    183    //check whether the path include the characters "bmp" at end
    184    strncpy(ext, &path[len - 3], 3);
    185    if (!(ext[0== 'b' && ext[1== 'm' && ext[2== 'p')) {
    186        printf("Error(CheckPath): the extension of the file is not bmp.\n");
    187        return -1;
    188    }

    189
    190    //check whether the file can be read or not
    191    fd = fopen(path, "r");
    192    if (!fd)
    193    {
    194        printf("Error(CheckPath): can not open the file.\n");
    195        return -1;
    196    }

    197    fclose(fd);
    198
    199    return 0;
    200}

    201
    202/**
    203 * 从文件中读取位图函数
    204 * 正确返回0,错误返回-1
    205 *
    206 * 使用方法:
    207 *     bmp=(Bitmap*)malloc(sizeof(Bitmap));
    208 *     ret=ReadBitmap(path, bmp);
    209 */

    210int ReadBitmap(char* path, Bitmap* bmp)
    211{
    212    int ret;
    213    FILE *fd;
    214
    215    //检查路径是否可读
    216    ret=CheckPath(path);
    217    if(ret==-1)
    218    {
    219        printf("Error(ReadBitmap): the path of the image is invalid.\n");
    220        return -1;
    221    }

    222
    223    //打开文件
    224    fd=fopen(path,"rb");
    225    if(fd==0)
    226    {
    227        printf("Error(ReadBitmap): can not open the image.\n");
    228        return -1;
    229    }

    230
    231    //读取文件信息头     14字节
    232    fread(&(bmp->bmfh.bfType),sizeof(WORD),1,fd);
    233    fread(&(bmp->bmfh.bfSize),sizeof(DWORD),1,fd);
    234    fread(&(bmp->bmfh.bfReserved1),sizeof(WORD),1,fd);
    235    fread(&(bmp->bmfh.bfReserved2),sizeof(WORD),1,fd);
    236    fread(&(bmp->bmfh.bfOffBits),sizeof(DWORD),1,fd);
    237
    238    //读取位图信息头    40字节
    239    fread(&(bmp->bmih.biSize),sizeof(DWORD),1,fd);
    240    fread(&(bmp->bmih.biWidth),sizeof(DWORD),1,fd);
    241    fread(&(bmp->bmih.biHeight),sizeof(DWORD),1,fd);
    242    fread(&(bmp->bmih.biPlanes),sizeof(WORD),1,fd);
    243    fread(&(bmp->bmih.biBitCount),sizeof(WORD),1,fd);
    244    fread(&(bmp->bmih.biCompression),sizeof(DWORD),1,fd);
    245    fread(&(bmp->bmih.biSizeImage),sizeof(DWORD),1,fd);
    246    fread(&(bmp->bmih.biXPelsPerMeter),sizeof(DWORD),1,fd);
    247    fread(&(bmp->bmih.biYPelsPerMeter),sizeof(DWORD),1,fd);
    248    fread(&(bmp->bmih.biClrUsed),sizeof(DWORD),1,fd);
    249    fread(&(bmp->bmih.biClrImportant),sizeof(DWORD),1,fd);
    250
    251    //创建位图结构
    252    ret=CreateBitmap(bmp, bmp->bmih.biWidth, bmp->bmih.biHeight, bmp->bmih.biBitCount);
    253    if(ret==-1)
    254    {
    255        printf("Error(CreateBitmap): can not CreateBitmap.\n");
    256        return -1;
    257    }

    258
    259    //读取图像数据
    260    //由于4字节对齐格式
    261    fseek(fd,bmp->bmfh.bfOffBits,SEEK_SET);    //定位到图像数据区
    262    ret=fread(bmp->imageData,bmp->imageSize,1,fd);
    263    if(ret==0)
    264    {
    265        if(feof(fd))    //if the file pointer point to the end of the file
    266        {
    267        }

    268        if(ferror(fd))  //if error happened while read the pixel data
    269        {
    270            printf("Error(ReadBitmap): can not read the pixel data.\n");
    271            fclose(fd);
    272            return -1;
    273        }

    274    }

    275
    276    //关闭文件
    277    fclose(fd);
    278    return 0;
    279}

    280
    281/**
    282 * 保存位图到文件中去
    283 * 正确返回0,错误返回-1
    284 *
    285 * 使用方法:
    286 *     bmp=(Bitmap*)malloc(sizeof(Bitmap));
    287 *     ret=SaveBitmap(path, bmp);
    288 */

    289int SaveBitmap(char* path, Bitmap* bmp)
    290{
    291    int ret;
    292    FILE *fd;
    293
    294    //检查路径是否正确
    295    int len = strlen(path) / sizeof(char);
    296    char ext[3];
    297    //check whether the path include the characters "bmp" at end
    298    strncpy(ext, &path[len - 3], 3);
    299    if (!(ext[0== 'b' && ext[1== 'm' && ext[2== 'p'))
    300    {
    301        printf("Error(SaveBitmap): the extension of the file is not bmp.\n");
    302        return -1;
    303    }

    304
    305    //打开文件
    306    fd=fopen(path,"wb");
    307    if(fd==0)
    308    {
    309        printf("Error(SaveBitmap): can not open the image.\n");
    310        return -1;
    311    }

    312
    313    //保存文件信息头     14字节
    314    fwrite(&(bmp->bmfh.bfType),sizeof(WORD),1,fd);
    315    fwrite(&(bmp->bmfh.bfSize),sizeof(DWORD),1,fd);
    316    fwrite(&(bmp->bmfh.bfReserved1),sizeof(WORD),1,fd);
    317    fwrite(&(bmp->bmfh.bfReserved2),sizeof(WORD),1,fd);
    318    fwrite(&(bmp->bmfh.bfOffBits),sizeof(DWORD),1,fd);
    319
    320    //保存位图信息头    40字节
    321    fwrite(&(bmp->bmih.biSize),sizeof(DWORD),1,fd);
    322    fwrite(&(bmp->bmih.biWidth),sizeof(DWORD),1,fd);
    323    fwrite(&(bmp->bmih.biHeight),sizeof(DWORD),1,fd);
    324    fwrite(&(bmp->bmih.biPlanes),sizeof(WORD),1,fd);
    325    fwrite(&(bmp->bmih.biBitCount),sizeof(WORD),1,fd);
    326    fwrite(&(bmp->bmih.biCompression),sizeof(DWORD),1,fd);
    327    fwrite(&(bmp->bmih.biSizeImage),sizeof(DWORD),1,fd);
    328    fwrite(&(bmp->bmih.biXPelsPerMeter),sizeof(DWORD),1,fd);
    329    fwrite(&(bmp->bmih.biYPelsPerMeter),sizeof(DWORD),1,fd);
    330    fwrite(&(bmp->bmih.biClrUsed),sizeof(DWORD),1,fd);
    331    fwrite(&(bmp->bmih.biClrImportant),sizeof(DWORD),1,fd);
    332
    333    //如果为8位,则 保存调色板
    334    RGBQUAD pal[256];
    335    int i;
    336    if(bmp->bitCount==8)
    337    {
    338        for(i=0;i<256;i++)
    339        {
    340            pal[i].rgbBlue=i;
    341            pal[i].rgbGreen=i;
    342            pal[i].rgbRed=i;
    343            pal[i].rgbReserved=0;
    344        }

    345        if(fwrite(pal,sizeof(RGBQUAD)*256,1,fd)!=1)
    346        {
    347            printf("Error(SaveBitmap): can not write Color Palette.\n");
    348            return -1;
    349        }

    350    }

    351
    352
    353    //保存图像数据
    354    ret=fwrite(bmp->imageData,bmp->imageSize,1,fd);
    355    if(ret!=1)
    356    {
    357        printf("Error(SaveBitmap): can not save the pixel data.\n");
    358        return -1;
    359    }

    360
    361    //关闭文件
    362    fclose(fd);
    363
    364    return 0;
    365}

    366
    367#endif // BMP_H_INCLUDED
    368
    369
    370
    371
    372
    373/*
    374****************************************Copyright (c)**************************************************
    375**                                           Feisky
    376**                            http://www.cnblogs.com/feisky/
    377**
    378**------------------------------------- File Info ------------------------------------------------------
    379** File name:           basicprocess.h
    380** Last modified Date:  2009-9-28
    381** Last Version:        1.0
    382** Descriptions:        位图图像基本处理函数  图像格式转换
    383**
    384** Created by:          Feisky
    385** Created date:        2009-9-28
    386** Version:             1.0
    387** Descriptions:        Preliminary version.
    388**
    389**------------------------------------------------------------------------------------------------------
    390*/

    391
    392#ifndef BASICPROCESS_H_
    393#define BASICPROCESS_H_
    394
    395#include "bmp.h"
    396#include <math.h>
    397/**
    398 * <font color="#3f7f5f">位图图像基本处理函数  图像格式转换</font>
    399 */

    400int RGB2Gray(Bitmap* src, Bitmap* dst)
    401{
    402    int ret;
    403    int n=0,i,j;
    404    BYTE r,g,b,gray;
    405
    406    //检查图像格式是否合法
    407    if(src->bitCount!=24)
    408    {
    409        printf("Error(RGB2Gray): the source image must be in RGB format.\n");
    410        return -1;
    411    }

    412
    413    //为dst图像分配数据空间
    414    ret=CreateBitmap(dst,src->width,src->height,8);
    415    if(ret==-1)
    416    {
    417        printf("Error(RGB2Gray): can't create target image.\n");
    418        return -1;
    419    }

    420
    421    //计算灰度数据
    422    for(i=0;i<src->height;i++)
    423    {
    424        n=0;
    425        for(j=0;j<src->width*3;j++,n++)
    426        {
    427            b=*(src->imageData+src->widthStep*(src->height-1-i)+j);
    428            j++;
    429            g=*(src->imageData+src->widthStep*(src->height-1-i)+j);
    430            j++;
    431            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
    432            gray=(r*19595 + g*38469 + b*7472>> 16;
    433            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=gray;
    434        }

    435    }

    436
    437    return 0;
    438}

    439
    440/**
    441 * Gray2RGB
    442 *
    443 * 使用方法:
    444 *        bmp=(Bitmap*)malloc(sizeof(Bitmap));
    445 *        ret=ReadBitmap(path, bmp);
    446 *        dstbmp=(Bitmap*)malloc(sizeof(Bitmap));
    447 *        ret=Gray2RGB(bmp,dstbmp);
    448 */

    449int Gray2RGB(Bitmap* src, Bitmap* dst)
    450{
    451    int ret;
    452    int n=0,i,j;
    453    BYTE r;
    454
    455    //检查图像格式是否合法
    456    if(src->bitCount!=8)
    457    {
    458        printf("Error(Gray2RGB): the source image must be in gray scale.\n");
    459        return -1;
    460    }

    461
    462    //为dst图像分配数据空间
    463    ret=CreateBitmap(dst,src->width,src->height,24);
    464    if(ret==-1)
    465    {
    466        printf("Error(Gray2RGB): can't create target image.\n");
    467        return -1;
    468    }

    469
    470    //计算灰度数据
    471    for(i=0;i<src->height;i++)
    472    {
    473        n=0;
    474        for(j=0;j<src->width;j++,n++)
    475        {
    476            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
    477            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
    478            n++;
    479            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
    480            n++;
    481            *(dst->imageData+dst->widthStep*(dst->height-1-i)+n)=r;
    482        }

    483    }

    484
    485    return 0;
    486}

    487
    488/**
    489 * Gray2BW 图像二值化
    490 *
    491 * 使用方法:
    492 *        bmp=(Bitmap*)malloc(sizeof(Bitmap));
    493 *        ret=ReadBitmap(path, bmp);
    494 *        dstbmp=(Bitmap*)malloc(sizeof(Bitmap));
    495 *        ret=Gray2BW(bmp,dstbmp);
    496 */

    497int Gray2BW(Bitmap* src, Bitmap* dst, int threshold)
    498{
    499    int ret;
    500    int n=0,i,j;
    501    BYTE r;
    502
    503    //检查图像格式是否合法
    504    if(src->bitCount!=8)
    505    {
    506        printf("Error(Gray2BW): the source image must be in gray scale.\n");
    507        return -1;
    508    }

    509
    510    //为dst图像分配数据空间
    511    ret=CreateBitmap(dst,src->width,src->height,8);
    512    if(ret==-1)
    513    {
    514        printf("Error(Gray2BW): can't create target image.\n");
    515        return -1;
    516    }

    517
    518    //计算灰度数据
    519    for(i=0;i<src->height;i++)
    520    {
    521        for(j=0;j<src->width;j++,n++)
    522        {
    523            r=*(src->imageData+src->widthStep*(src->height-1-i)+j);
    524            if(r>=threshold)
    525            {
    526                n=255;
    527            }

    528            else
    529            {
    530                n=0;
    531            }

    532            *(dst->imageData+dst->widthStep*(dst->height-1-i)+j)=n;
    533        }

    534    }

    535
    536    return 0;
    537}

    538
    539/**
    540 *  rgb2hsv
    541 *  r,g,b values are from 0 to 1
    542 *  h = [0,360], s = [0,1], v = [0,1]
    543 *  if s == 0, then h = -1 (undefined)
    544 *  使用方法:
    545 *      rgb2hsv(0.2,0.3,0.3,&x,&y,&z);
    546 */

    547void rgb2hsv(float R, float G, float B, float *H, float *S, float* V)
    548{
    549    float min, max, delta,tmp;
    550    tmp = R<G?R:G;
    551    min = tmp<B?tmp:B;
    552    tmp = R>G?R:G;
    553    max = tmp>B?tmp:B;
    554    *= max; // v
    555
    556    delta = max - min;
    557
    558    if( max != 0 )
    559      *= delta / max; // s
    560    else
    561    {
    562       // r = g = b = 0 // s = 0, v is undefined
    563      *= 0;
    564      *= -1;
    565      return;
    566    }

    567    if( R == max )
    568        *= ( G - B ) / delta; // between yellow & magenta
    569   else if( G == max )
    570        *= 2 + ( B - R ) / delta; // between cyan & yellow
    571   else
    572       *= 4 + ( R - G ) / delta; // between magenta & cyan
    573
    574    (*H) *= 60// degrees
    575    if*< 0 )
    576       (*H) += 360;
    577}

    578
    579
    580/**
    581 *  hsv2rgb
    582 *  r,g,b values are from 0 to 1
    583 *  h = [0,360], s = [0,1], v = [0,1]
    584 *  if s == 0, then h = -1 (undefined)
    585 *  使用方法:
    586 *       hsv2rgb(60,0.3,0.5,&x,&y,&z);
    587 */

    588void hsv2rgb(float H, float S, float V, float *R, float *G, float *B)
    589{
    590     int i;
    591    float f, p, q, t;
    592
    593    if( S == 0 )
    594    {
    595        *=*= *= V;
    596        return;
    597    }

    598
    599    H /= 60// sector 0 to 5
    600    i = floor( H );
    601    f = H - i; // factorial part of h
    602    p = V * ( 1 - S );
    603    q = V * ( 1 - S * f );
    604    t = V * ( 1 - S * ( 1 - f ) );
    605
    606    switch( i )
    607    {
    608    case 0:
    609        *= V;
    610        *= t;
    611        *= p;
    612       break;
    613    case 1:
    614       *= q;
    615       *= V;
    616       *= p;
    617       break;
    618    case 2:
    619       *= p;
    620       *= V;
    621       *= t;
    622       break;
    623    case 3:
    624       *= p;
    625       *= q;
    626       *= V;
    627       break;
    628    case 4:
    629       *= t;
    630       *= p;
    631       *= V;
    632       break;
    633    default// case 5:
    634       *= V;
    635       *= p;
    636       *= q;
    637       break;
    638    }

    639}

    640
    641/**
    642 * 直方图均衡化
    643 * 返回 0正确 -1错误
    644 */

    645int HistEqualization(Bitmap* dstBmp, Bitmap* srcBmp)
    646{
    647    return 0;
    648}

    649
    650/*
    651 * 中值滤波
    652*/

    653
    654int MedFilt(Bitmap* dstBmp, Bitmap* srcBmp)
    655{
    656    return 0;
    657}

    658
    659#endif /* BASICPROCESS_H_ */

  • 相关阅读:
    python-pycharm中使用anaconda部署python环境
    Spring Boot 整合 Redis 实现缓存操作
    Spring中的ThreadPoolTaskExecutor
    Redis-基本数据类型与内部存储结构
    Redis如何存储对象与集合示例详解
    redis存储对象
    java在注解中绑定方法参数的解决方案
    spring boot整合JMS(ActiveMQ实现)
    springboot集成activemq
    NodeJS、NPM安装配置步骤(windows版本)
  • 原文地址:https://www.cnblogs.com/feisky/p/1587698.html
Copyright © 2020-2023  润新知