示例#1
0
void imProcessFillHoles(const imImage* image, imImage* NewImage, int connect)
{
  // finding regions in the inverted image will isolate only the holes.
  imProcessNegative(image, NewImage);

  imImage *region_image = imImageCreate(image->width, image->height, IM_GRAY, IM_USHORT);
  if (!region_image)
    return;

  int holes_count = imAnalyzeFindRegions(NewImage, region_image, connect, 0);
  if (!holes_count)
  {
    imImageCopy(image, NewImage);
    imImageDestroy(region_image);
    return;
  }

  imushort* region_data = (imushort*)region_image->data[0];
  imbyte* dst_data = (imbyte*)NewImage->data[0];

  for (int i = 0; i < image->count; i++)
  {
    if (*region_data)
      *dst_data = 1;
    else
      *dst_data = !(*dst_data);  // Fix negative data.

    region_data++;
    dst_data++;
  }

  imImageDestroy(region_image);
}
示例#2
0
void imProcessRemoveByArea(const imImage* image, imImage* NewImage, int connect, int start_size, int end_size, int inside)
{
  imImage *region_image = imImageCreate(image->width, image->height, IM_GRAY, IM_USHORT);
  if (!region_image)
    return;

  int region_count = imAnalyzeFindRegions(image, region_image, connect, 1); 
  if (!region_count)
  {
    imImageClear(NewImage);
    imImageDestroy(region_image);
    return;
  }

  if (end_size == 0)
    end_size = image->width*image->height;

  int outside;
  if (inside)
  {
    /* remove from inside */
    inside = 0;
    outside = 1;
  }
  else
  {
    /* remove from outside */
    inside = 1;
    outside = 0;
  }

  int* area_data = (int*)malloc(region_count*sizeof(int));
  imAnalyzeMeasureArea(region_image, area_data, region_count);

  imushort* region_data = (imushort*)region_image->data[0];
  imbyte* img_data = (imbyte*)NewImage->data[0];

  for (int i = 0; i < image->count; i++)
  {
    if (*region_data)
    {
      int area = area_data[(*region_data) - 1];
      if (area < start_size || area > end_size)
        *img_data = (imbyte)outside;
      else
        *img_data = (imbyte)inside;
    }
    else
      *img_data = 0;

    region_data++;
    img_data++;
  }

  free(area_data);
  imImageDestroy(region_image);
}
示例#3
0
int imProcessGrayMorphClose(const imImage* src_image, imImage* dst_image, int kernel_size)
{
  imImage*temp = imImageClone(src_image);
  if (!temp)
    return 0;

  if (!imProcessGrayMorphDilate(src_image, temp, kernel_size)) 
    {imImageDestroy(temp); return 0;}
  if (!imProcessGrayMorphErode(temp, dst_image, kernel_size)) 
    {imImageDestroy(temp); return 0;}

  imImageDestroy(temp);
  return 1;
}
示例#4
0
int imProcessGrayMorphGradient(const imImage* src_image, imImage* dst_image, int kernel_size)
{
  imImage*temp = imImageClone(src_image);
  if (!temp)
    return 0;

  if (!imProcessGrayMorphDilate(src_image, temp, kernel_size)) 
    {imImageDestroy(temp); return 0;}
  if (!imProcessGrayMorphErode(src_image, dst_image, kernel_size)) 
    {imImageDestroy(temp); return 0;}

  imProcessArithmeticOp(temp, dst_image, dst_image, IM_BIN_DIFF);

  imImageDestroy(temp);
  return 1;
}
示例#5
0
文件: im_fft.cpp 项目: Vulcanior/IUP
void imProcessCrossCorrelation(const imImage* src_image1, const imImage* src_image2, imImage* dst_image)
{
  imImage *tmp_image = imImageCreate(src_image2->width, src_image2->height, src_image2->color_space, IM_COMPLEX);
  if (!tmp_image) 
    return;

  if (src_image2->data_type != IM_COMPLEX)
    imConvertDataType(src_image2, tmp_image, 0, 0, 0, 0);
  else
    imImageCopy(src_image2, tmp_image);

  if (src_image1->data_type != IM_COMPLEX)
    imConvertDataType(src_image1, dst_image, 0, 0, 0, 0);
  else
    imImageCopy(src_image1, dst_image);

  imProcessFFTraw(tmp_image, 0, 1, 1);   // forward, centered, normalized
  imProcessFFTraw(dst_image, 0, 1, 1);

  imProcessMultiplyConj(dst_image, tmp_image, dst_image);

  imProcessFFTraw(dst_image, 1, 1, 1);   // inverse, uncentered, normalized
  imProcessSwapQuadrants(dst_image, 0);  // from origin to center

  imImageDestroy(tmp_image);
}
示例#6
0
int item_paste_action_cb(Ihandle* item_paste) 
{
  if (save_check(item_paste))
  {
    Ihandle* canvas = IupGetDialogChild(item_paste, "CANVAS");
    imImage* old_image = (imImage*)IupGetAttribute(canvas, "IMAGE");

    Ihandle *clipboard = IupClipboard();
    imImage* image = IupGetNativeHandleImage(IupGetAttribute(clipboard, "NATIVEIMAGE"));
    IupDestroy(clipboard);

    if (!image)
    {
      show_error("Invalid Clipboard Data", 1);
      return IUP_DEFAULT;
    }

    /* we are going to support only RGB images with no alpha */
    imImageRemoveAlpha(image);
    if (image->color_space != IM_RGB)
    {
      imImage* new_image = imImageCreateBased(image, -1, -1, IM_RGB, -1);
      imConvertColorSpace(image, new_image);
      imImageDestroy(image);

      image = new_image;
    }

    /* create OpenGL compatible data */
    imImageGetOpenGLData(image, NULL);

    imImageSetAttribString(image, "FileFormat", "JPEG");

    IupSetAttribute(canvas, "DIRTY", "Yes");
    IupSetAttribute(canvas, "IMAGE", (char*)image);
    IupSetAttribute(canvas, "FILENAME", NULL);
    IupSetAttribute(IupGetDialog(canvas), "TITLE", "Untitled - Simple Paint");

    IupUpdate(canvas);

    if (old_image)
      imImageDestroy(old_image);
  }
  return IUP_DEFAULT;
}
示例#7
0
int imProcessGrayMorphDilate(const imImage* src_image, imImage* dst_image, int kernel_size)
{
  imImage* kernel = imImageCreate(kernel_size, kernel_size, IM_GRAY, IM_INT);
  imImageSetAttribute(kernel, "Description", IM_BYTE, -1, (void*)"Dilate");
  // Kernel is all zeros
  int ret = imProcessGrayMorphConvolve(src_image, dst_image, kernel, 1);
  imImageDestroy(kernel);
  return ret;
}
示例#8
0
void set_new_image(Ihandle* canvas, imImage* image, const char* filename, int dirty)
{
  imImage* old_image = (imImage*)IupGetAttribute(canvas, "IMAGE");
  Ihandle* size_lbl = IupGetDialogChild(canvas, "SIZELABEL");
  Ihandle* zoom_val = IupGetDialogChild(canvas, "ZOOMVAL");

  if (filename)
  {
    IupSetStrAttribute(canvas, "FILENAME", filename);
    IupSetfAttribute(IupGetDialog(canvas), "TITLE", "%s - Simple Paint", str_filetitle(filename));
  }
  else
  {
    IupSetAttribute(canvas, "FILENAME", NULL);
    IupSetAttribute(IupGetDialog(canvas), "TITLE", "Untitled - Simple Paint");
  }

  /* we are going to support only RGB images with no alpha */
  imImageRemoveAlpha(image);
  if (image->color_space != IM_RGB)
  {
    imImage* new_image = imImageCreateBased(image, -1, -1, IM_RGB, -1);
    imConvertColorSpace(image, new_image);
    imImageDestroy(image);

    image = new_image;
  }

  /* default file format */
  const char* format = imImageGetAttribString(image, "FileFormat");
  if (!format)
    imImageSetAttribString(image, "FileFormat", "JPEG");
    
  IupSetAttribute(canvas, "DIRTY", dirty? "Yes": "No");
  IupSetAttribute(canvas, "IMAGE", (char*)image);

  IupSetfAttribute(size_lbl, "TITLE", "%d x %d px", image->width, image->height);

  if (old_image)
    imImageDestroy(old_image);

  IupSetDouble(zoom_val, "VALUE", 0);
  zoom_update(canvas, 0);
}
示例#9
0
文件: imlua_image.c 项目: LuaDist/im
/*****************************************************************************\
 image:Destroy()
\*****************************************************************************/
static int imluaImageDestroy (lua_State *L)
{
  imImage** image_p = imlua_rawcheckimage(L, 1);
  if (!(*image_p))
    luaL_argerror(L, 1, "destroyed imImage");

  imImageDestroy(*image_p);
  *image_p = NULL; /* mark as destroyed */
  return 0;
}
示例#10
0
文件: imlua_image.c 项目: LuaDist/im
/*****************************************************************************\
 gc
\*****************************************************************************/
static int imluaImage_gc (lua_State *L)
{
  imImage** image_p = imlua_rawcheckimage(L, 1);
  if (*image_p)
  {
    imImageDestroy(*image_p);
    *image_p = NULL; /* mark as destroyed */
  }

  return 0;
}
示例#11
0
int imProcessGrayMorphConvolve(const imImage* src_image, imImage* dst_image, const imImage *kernel, int ismax)
{
  int ret = 0;

  int counter = imProcessCounterBegin("Gray Morphological Convolution");
  const char* msg = (const char*)imImageGetAttribute(kernel, "Description", NULL, NULL);
  if (!msg) msg = "Processing...";
  imCounterTotal(counter, src_image->depth*src_image->height, msg);

  imImage* fkernel = NULL;
    
  if ((src_image->data_type == IM_FLOAT || src_image->data_type == IM_DOUBLE) && 
       kernel->data_type != src_image->data_type)
  {
    fkernel = imImageCreate(kernel->width, kernel->height, IM_GRAY, src_image->data_type);
    imProcessConvertDataType(kernel, fkernel, 0, 0, 0, IM_CAST_DIRECT);
    kernel = fkernel;
  }

  for (int i = 0; i < src_image->depth; i++)
  {
    switch(src_image->data_type)
    {
    case IM_BYTE:
      ret = DoGrayMorphConvolve((imbyte*)src_image->data[i], (imbyte*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (int)0);
      break;                                                                                
    case IM_SHORT:
      ret = DoGrayMorphConvolve((short*)src_image->data[i], (short*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (int)0);
      break;                                                                                
    case IM_USHORT:
      ret = DoGrayMorphConvolve((imushort*)src_image->data[i], (imushort*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (int)0);
      break;                                                                                
    case IM_INT:                                                                           
      ret = DoGrayMorphConvolve((int*)src_image->data[i], (int*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (int)0);
      break;                                                                                
    case IM_FLOAT:
      ret = DoGrayMorphConvolve((float*)src_image->data[i], (float*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (float)0);
      break;                                                                                
    case IM_DOUBLE:
      ret = DoGrayMorphConvolve((double*)src_image->data[i], (double*)dst_image->data[i], src_image->width, src_image->height, kernel, counter, ismax, (double)0);
      break;
    }
    
    if (!ret) 
      break;
  }

  if (fkernel) imImageDestroy(fkernel);
  imProcessCounterEnd(counter);

  return ret;
}
示例#12
0
static int cbDialogClose(Ihandle* iup_dialog)
{
  cdCanvas* cd_canvas = (cdCanvas*)IupGetAttribute(iup_dialog, "cdCanvas");
  imImage* image = (imImage*)IupGetAttribute(iup_dialog, "imImage");

  if (cd_canvas) cdKillCanvas(cd_canvas);
  if (image) imImageDestroy(image);

  IupSetAttribute(iup_dialog, "cdCanvas", NULL);
  IupSetAttribute(iup_dialog, "imImage", NULL);

  return IUP_CLOSE;
}
示例#13
0
static void ShowImage(char* file_name, Ihandle* iup_dialog)
{
  int error;
  imImage* image = (imImage*)IupGetAttribute(iup_dialog, "imImage");
  if (image) imImageDestroy(image);
  IupSetAttribute(iup_dialog, "imImage", NULL);

  image = imFileImageLoadBitmap(file_name, 0, &error);
  if (error) PrintError(error);
  if (!image) return;

  IupSetAttribute(iup_dialog, "imImage", (char*)image);
  IupStoreAttribute(iup_dialog, "TITLE", file_name);

  cbCanvasRepaint(iup_dialog); /* we can do this because canvas inherit attributes from the dialog */
}
示例#14
0
int item_exit_action_cb(Ihandle* item_exit)
{
  Ihandle* dlg = IupGetDialog(item_exit);
  Ihandle* config = (Ihandle*)IupGetAttribute(dlg, "CONFIG");
  Ihandle* canvas = IupGetDialogChild(dlg, "CANVAS");
  imImage* image = (imImage*)IupGetAttribute(canvas, "IMAGE");

  if (!save_check(item_exit))
    return IUP_IGNORE;  /* to abort the CLOSE_CB callback */

  if (image)
    imImageDestroy(image);

  IupConfigDialogClosed(config, dlg, "MainWindow");
  IupConfigSave(config);
  IupDestroy(config);
  return IUP_CLOSE;
}
示例#15
0
static int bt1_cb(Ihandle* self)
{
  imImage* image;
  int w, h;
  void* gldata;
  int ii = tabs_get_index();
  IupGetIntInt(plot[ii], "DRAWSIZE", &w, &h);
  gldata = malloc(w*h*3);
  image = imImageCreate(w, h, IM_RGB, IM_BYTE);
  IupMglPlotPaintTo(plot[ii], "RGB", w, h, 0, gldata);
  imConvertPacking(gldata, image->data[0], w, h, 3, 3, IM_BYTE, 1);
  imProcessFlip(image, image);
  imFileImageSave("../mglplot.png", "PNG", image);
  free(gldata);
  imImageDestroy(image);
  (void)self;
  return IUP_DEFAULT;
}
示例#16
0
void new_file(Ihandle* ih, imImage* image)
{
  Ihandle* dlg = IupGetDialog(ih);
  Ihandle* canvas = IupGetDialogChild(dlg, "CANVAS");
  imImage* old_image = (imImage*)IupGetAttribute(canvas, "IMAGE");

  IupSetAttribute(dlg, "TITLE", "Untitled - Simple Paint");
  IupSetAttribute(canvas, "FILENAME", NULL);
  IupSetAttribute(canvas, "DIRTY", "NO");

  IupSetAttribute(canvas, "IMAGE", (char*)image);

  /* create OpenGL compatible data */
  imImageGetOpenGLData(image, NULL);

  IupUpdate(canvas);

  if (old_image)
    imImageDestroy(old_image);
}
示例#17
0
void open_file(Ihandle* ih, const char* filename)
{
  imImage* image = read_file(filename);
  if (image)
  {
    Ihandle* dlg = IupGetDialog(ih);
    Ihandle* canvas = IupGetDialogChild(dlg, "CANVAS");
    Ihandle* config = (Ihandle*)IupGetAttribute(canvas, "CONFIG");
    imImage* old_image = (imImage*)IupGetAttribute(canvas, "IMAGE");

    IupSetfAttribute(dlg, "TITLE", "%s - Simple Paint", str_filetitle(filename));
    IupSetStrAttribute(canvas, "FILENAME", filename);
    IupSetAttribute(canvas, "DIRTY", "NO");
    IupSetAttribute(canvas, "IMAGE", (char*)image);

    IupUpdate(canvas);

    if (old_image)
      imImageDestroy(old_image);

    IupConfigRecentUpdate(config, filename);
  }
}
示例#18
0
imImage* read_file(const char* filename)
{
  int error;
  imImage* image = imFileImageLoadBitmap(filename, 0, &error);
  if (error) 
    show_file_error(error);
  else
  {
    /* we are going to support only RGB images with no alpha */
    imImageRemoveAlpha(image);
    if (image->color_space != IM_RGB)
    {
      imImage* new_image = imImageCreateBased(image, -1, -1, IM_RGB, -1);
      imConvertColorSpace(image, new_image);
      imImageDestroy(image);

      image = new_image;
    }

    /* create OpenGL compatible data */
    imImageGetOpenGLData(image, NULL);
  }
  return image;
}
示例#19
0
int imConvertToBitmap(const imImage* src_image, imImage* dst_image, int cpx2real, float gamma, int absolute, int cast_mode)
#endif
{
    assert(src_image);
    assert(dst_image);

    if (!imImageMatchSize(src_image, dst_image) || !imImageIsBitmap(dst_image))
        return IM_ERR_DATA;

#ifdef IM_PROCESS
    int counter = imProcessCounterBegin("Building Bitmap");
#else
    int counter = imCounterBegin("Building Bitmap");
#endif

    int ret;
    if (src_image->data_type == IM_BYTE)
    {
        // NO data type conversion, only color mode conversion
#ifdef IM_PROCESS
        ret = imProcessConvertColorSpace(src_image, dst_image);
#else
        ret = imConvertColorSpace(src_image, dst_image);
#endif
    }
    else
    {
        if (src_image->color_space == IM_RGB ||
                src_image->color_space == IM_GRAY)
        {
            // data type conversion, but NO color mode conversion
#ifdef IM_PROCESS
            ret = imProcessConvertDataType(src_image, dst_image, cpx2real, gamma, absolute, cast_mode);
#else
            ret = imConvertDataType(src_image, dst_image, cpx2real, gamma, absolute, cast_mode);
#endif
        }
        else
        {
            // data type conversion AND color mode conversion
            imImage* temp_image = imImageCreate(src_image->width, src_image->height, dst_image->color_space, src_image->data_type);
            if (!temp_image)
                ret = IM_ERR_MEM;
            else
            {
                // first convert color_mode in the bigger precision
#ifdef IM_PROCESS
                ret = imProcessConvertColorSpace(src_image, temp_image);
#else
                ret = imConvertColorSpace(src_image, temp_image);
#endif
                if (ret == IM_ERR_NONE)
                {
                    // second just convert data type
#ifdef IM_PROCESS
                    ret = imProcessConvertDataType(temp_image, dst_image, cpx2real, gamma, absolute, cast_mode);
#else
                    ret = imConvertDataType(temp_image, dst_image, cpx2real, gamma, absolute, cast_mode);
#endif
                }
                imImageDestroy(temp_image);
            }
        }
    }

#ifdef IM_PROCESS
    imProcessCounterEnd(counter);
#else
    imCounterEnd(counter);
#endif

    return ret;
}
示例#20
0
void imAnalyzeMeasureHoles(const imImage* image, int connect, int* count_data, int* area_data, float* perim_data)
{
  int i;
  imImage *inv_image = imImageCreate(image->width, image->height, IM_BINARY, IM_BYTE);
  imbyte* inv_data = (imbyte*)inv_image->data[0];
  imushort* img_data = (imushort*)image->data[0];

  // finds the holes in the inverted image
  for (i = 0; i < image->count; i++)
  {
    if (*img_data)
      *inv_data = 0;
    else
      *inv_data = 1;

    img_data++;
    inv_data++;
  }

  imImage *holes_image = imImageClone(image);
  if (!holes_image)
    return;

  int holes_count = imAnalyzeFindRegions(inv_image, holes_image, connect, 0);
  imImageDestroy(inv_image);

  if (!holes_count)
  {
    imImageDestroy(holes_image);
    return;
  }

  // measure the holes area
  int* holes_area = (int*)malloc(holes_count*sizeof(int));
  imAnalyzeMeasureArea(holes_image, holes_area, holes_count);

  float* holes_perim = 0;
  if (perim_data) 
  {
    holes_perim = (float*)malloc(holes_count*sizeof(int));
    imAnalyzeMeasurePerimeter(holes_image, holes_perim, holes_count);
  }

  imushort* holes_data = (imushort*)holes_image->data[0];
  img_data = (imushort*)image->data[0];

  // holes do not touch the border
  for (int y = 1; y < image->height-1; y++) 
  {
    int offset_up = (y+1)*image->width;
    int offset = y*image->width;
    int offset_dw = (y-1)*image->width;

    for (int x = 1; x < image->width-1; x++)
    {
      int hole_index = holes_data[offset+x];

      if (hole_index && holes_area[hole_index-1]) // a hole not yet used
      {
        // if the hole has not been used, 
        // it is the first time we encounter a pixel of this hole.
        // then it is a pixel from the hole border.
        // now find which region this hole is inside.
        // a 4 connected neighbour is necessarilly a valid region or 0.

        int region_index = 0;
        if (img_data[offset_up + x]) region_index = img_data[offset_up + x];
        else if (img_data[offset + x+1]) region_index = img_data[offset + x+1];
        else if (img_data[offset + x-1]) region_index = img_data[offset + x-1]; 
        else if (img_data[offset_dw+x]) region_index = img_data[offset_dw+x];

        if (!region_index) continue;

        if (count_data) count_data[region_index-1]++;
        if (area_data) area_data[region_index-1] += holes_area[hole_index-1];
        if (perim_data) perim_data[region_index-1] += holes_perim[hole_index-1];
        holes_area[hole_index-1] = 0; // mark hole as used
      }
    }
  }

  if (holes_perim) free(holes_perim);
  free(holes_area);
  imImageDestroy(holes_image);
}