#include "mywin_inc.h" #include "mywin_user_photo.h" #include "ff.h" #include "picdeco.h" #include "bmp.h" #include "png.h" #include #include "system_file.h" #define WIN_PHOTO_TYPE "WIN_PhotoStruct" static const char *g_popup_itmes[]= { "设置为背景", "转换为灰度", "转换为位图", "退出", }; WIN_PhotoStruct *WIN_CreatPhoto (WIN_WindowStruct *base, void (*msgLoop)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg), int x,int y,int x_size,int y_size) { //重设消息循环 if (msgLoop==0) { msgLoop=(void (*)(struct _WIN_WindowStruct *win,WIN_MsgStruct *msg))PHOTO_defaultMsgLoop; } WIN_PhotoStruct *ret=mymalloc (sizeof ( WIN_PhotoStruct)); //调用父类的构造函数 if (ret) { mymemset (ret,0,sizeof ( WIN_PhotoStruct)); if (0==WIN_CreatWindowExt((WIN_WindowStruct *)ret,base,msgLoop,x,y,x_size,y_size)) { //创建失败 myfree (ret); ret=0; } else { //构造 ((WIN_WindowStruct *)ret)->deleteWindow=(void (*)(struct _WIN_WindowStruct *win))WIN_DeletePhoto; ((WIN_WindowStruct *)ret)->winType=WIN_PHOTO_TYPE; ((WIN_WindowStruct *)ret)->intercept=1; ((WIN_WindowStruct *)ret)->bkcolor=0x808080; ((WIN_WindowStruct *)ret)->color=0xffffff; } } return ret; } void WIN_DeletePhoto (WIN_PhotoStruct *photo) { if (photo->memData) { myfree (photo->memData); } if (photo->memDataGray) { myfree (photo->memDataGray); } if (photo->memDataBit) { myfree (photo->memDataBit); } //调用父类的销毁函数 WIN_DeleteWindow ( (WIN_WindowStruct *)photo); } //设置图片 void PHOTO_SetPic (WIN_PhotoStruct *photo,WIN_PicStruct *pic) { mymemcpy(&((WIN_WindowStruct *)photo)->pic,pic,sizeof(WIN_PicStruct)); mymemcpy(&photo->pic,pic,sizeof(WIN_PicStruct)); } static int go_trsGray (void *ptr) { WIN_PhotoStruct *photo =ptr; u16 *img=photo->memDataGray; for (int i=0;ipic.xsize*photo->pic.ysize;i++) { img[i]=RGB2GRAY (photo->pic.data[i]); img[i]=GRAY2RGB (img[i]); } photo->grayTrs=1; return 0; } //转化为灰度图 void PHOTO_TransforGray (WIN_PhotoStruct *photo) { if (photo->memDataGray==0) { photo->memDataGray=mymalloc (photo->pic.xsize*photo->pic.ysize*2); } if ((photo->memDataGray)&&(photo->grayTrs==0)) { WORKING_DoWork ((WIN_WindowStruct *)photo,"正在生成灰度图。。。",go_trsGray,photo); } if (photo->grayTrs) { if (photo->pic.data!=photo->memDataGray) photo->pic.data=photo->memDataGray; else photo->pic.data=photo->memData; } } static u16 getBit (WIN_PicStruct *pic,int x,int y) { if ((x<0||x>=pic->xsize)||(y<0||y>=pic->ysize)) return 0; else return pic->data[y*pic->xsize+x]&0x1f; } static u16 setBit (WIN_PicStruct *pic,int x,int y,int color) { if ((x<0||x>=pic->xsize)||(y<0||y>=pic->ysize)) return 0; else { if (color>0x1f) return pic->data[y*pic->xsize+x]=0x1f; else if (color<0) return pic->data[y*pic->xsize+x]=0; else return pic->data[y*pic->xsize+x]=color; } } static u16 getBitRand (WIN_PicStruct *pic,int lev,int x,int y) { if ((getBit(pic,x,y)&0x1f)>lev) return 0x1f; else return 0; } static int do_work (void *ptr) { WIN_PhotoStruct *photo=ptr; if (photo->memDataBit) { u16 *ptr=photo->memDataBit; u16 *src=photo->memDataGray; long lev=0; for (int i=0;ipic.xsize*photo->pic.ysize;i++) { ptr[i]=0x1f&src[i]; lev+=ptr[i]; } lev/=photo->pic.xsize*photo->pic.ysize; photo->pic.data=ptr; for (int y=0;ypic.ysize;y++) { for (int x=0;xpic.xsize;x++) { u16 color_old=ptr[y*photo->pic.xsize+x]; ptr[y*photo->pic.xsize+x]=getBitRand(&photo->pic,lev,x,y); int quant_error=color_old-ptr[y*photo->pic.xsize+x]; setBit (&photo->pic,x+1,y, getBit(&photo->pic,x+1,y)+quant_error *7/16); setBit (&photo->pic,x-1,y+1, getBit(&photo->pic,x-1,y+1)+quant_error *3/16); setBit (&photo->pic,x,y+1, getBit(&photo->pic,x,y+1)+quant_error *5/16); setBit (&photo->pic,x+1,y+1, getBit(&photo->pic,x+1,y+1)+quant_error *1/16); if (ptr[y*photo->pic.xsize+x]) ptr[y*photo->pic.xsize+x]=0xffff; } } photo->pic.data=photo->memData; photo->bitTrs=1; } return 0; } //转化为位图 int PHOTO_TransforBit (WIN_PhotoStruct *photo) { if (photo->grayTrs) { if (photo->memDataBit==0) { photo->memDataBit=mymalloc (photo->pic.xsize*photo->pic.ysize*2); WORKING_DoWork ((WIN_WindowStruct *)photo,"正在生成位图。。。",do_work,photo); } } if (photo->bitTrs) { if (photo->pic.data!=photo->memDataBit) photo->pic.data=photo->memDataBit; else photo->pic.data=photo->memData; } return 0; } //消息框的绘制函数 void PHOTO_DefaultPaint (WIN_PhotoStruct *photo) { WIN_WindowStruct *win=(WIN_WindowStruct *)photo; WIN_PicStruct *pic=&win->pic; int xsize=win->x_size; int ysize=win->y_size; if(pic->format==PIC_FORMAT_RGB565) WIN_FillRect (0,0,xsize,ysize,pic->data,0,0,pic->xsize,pic->ysize); else if(pic->format==PIC_FORMAT_ARGB8888) WIN_FillRectAlpha (0,0,xsize,ysize,pic->data,0,0,pic->xsize,pic->ysize); } static void PHOTO_Enter (WIN_PhotoStruct *photo,int x,int y) { int index=POPUP_SelectItem ((WIN_WindowStruct *)photo,(char **)g_popup_itmes,4,x,y); if (index==0) { //设置为背景 WIN_PicStruct pic={0}; WIN_PicStruct *win_pic=&((WIN_WindowStruct *)photo)->pic; WIN_WindowStruct *home=WIN_GetWinByTitle(0,"home"); if(home) { pic.data=home->pic.data; pic.xsize=home->pic.xsize; pic.ysize=home->pic.ysize; int xsize=pic.xsize;int ysize=pic.ysize; if (xsize>win_pic->xsize) xsize=win_pic->xsize; if (ysize>win_pic->ysize) ysize=win_pic->ysize; for (int i=0;idata[i*win_pic->xsize+j]; } } } } else if (index==1) { //转换为灰度图 PHOTO_TransforGray (photo); ((WIN_WindowStruct *)photo)->pic.data=photo->pic.data+photo->x_off+photo->y_off*photo->pic.xsize; ((WIN_WindowStruct *)photo)->pic.ysize=photo->pic.ysize-photo->y_off; WIN_SetInvalid ((WIN_WindowStruct *)photo); } else if (index==2) { //转换为位图 PHOTO_TransforBit (photo); ((WIN_WindowStruct *)photo)->pic.data=photo->pic.data+photo->x_off+photo->y_off*photo->pic.xsize; ((WIN_WindowStruct *)photo)->pic.ysize=photo->pic.ysize-photo->y_off; WIN_SetInvalid ((WIN_WindowStruct *)photo); } else if (index==3) { //退出 ((WIN_WindowStruct *)photo)->deleteWindow((WIN_WindowStruct *)photo); } } //消息框的消息处理函数 void PHOTO_defaultMsgLoop (WIN_PhotoStruct *photo,WIN_MsgStruct *msg) { WIN_MoveStruct *m=0; WIN_KeyStruct *k=0; switch (msg->msg) { case WIN_MSG_PAINT: PHOTO_DefaultPaint(photo); break; case WIN_MSG_KEY: k=msg->data.p; if (k->shortPress&KEY_VALUE_HOME) ((WIN_WindowStruct *)photo)->deleteWindow((WIN_WindowStruct *)photo); else if (k->shortPress&KEY_VALUE_ENTER) { PHOTO_Enter(photo,100,100); } break; case WIN_MSG_MOVE: m=msg->data.p; switch (m->moveType) { case MOVE_DATA_MOVED: //等待上次的显示刷新 //while (LCD_GetLayerUpdataStat()==0){} photo->x_off-=m->x_move; photo->y_off-=m->y_move; if (photo->x_off<0) photo->x_off=0; if (photo->y_off<0) photo->y_off=0; if (photo->pic.xsize>((WIN_WindowStruct *)photo)->x_size) { if (photo->x_off>photo->pic.xsize-((WIN_WindowStruct *)photo)->x_size) photo->x_off=photo->pic.xsize-((WIN_WindowStruct *)photo)->x_size; } else photo->x_off=0; if (photo->pic.ysize>((WIN_WindowStruct *)photo)->y_size) { if (photo->y_off>photo->pic.ysize-((WIN_WindowStruct *)photo)->y_size) photo->y_off=photo->pic.ysize-((WIN_WindowStruct *)photo)->y_size; } else photo->y_off=0; ((WIN_WindowStruct *)photo)->pic.data=photo->pic.data+photo->x_off+photo->y_off*photo->pic.xsize; ((WIN_WindowStruct *)photo)->pic.ysize=photo->pic.ysize-photo->y_off; WIN_SetInvalid ((WIN_WindowStruct *)photo); break; case MOVE_DATA_LONG: PHOTO_Enter(photo,m->x_move,m->y_move); break; default: WIN_DefaultMsgLoop((WIN_WindowStruct *)photo,msg); break; } break; default: WIN_DefaultMsgLoop((WIN_WindowStruct *)photo,msg); break; } } typedef struct { u8 *name; BITMAP_Struct *bitmap; }decode_jpg_struct; //图片解码工作函数 static int decode_jpg ( void *ptr) { decode_jpg_struct *p=ptr; return JPEG_Decode (p->name,p->bitmap); } typedef struct { u8 *name; BMP_DecodeStruct *bmp; }decode_bmp_struct; static int decode_bmp (void *ptr) { decode_bmp_struct *p=ptr; return BMP_Decode (p->name,p->bmp); } typedef struct { char *name; WIN_PicStruct *pic; }decode_png_struct; //解码png图片,成功返回1,失败返回0 static int decode_png(void *ptr) { decode_png_struct *p=ptr; WIN_PicStruct *pic=p->pic; char *name=p->name; int png_err=0; png_image image; /* The control structure used by libpng */ /* Initialize the 'png_image' structure. */ memset(&image, 0, (sizeof image)); image.version = PNG_IMAGE_VERSION; /* The first argument is the file to read: */ if (png_image_begin_read_from_file(&image, name) != 0) { image.format = PNG_FORMAT_BGRA; pic->data = mymalloc(PNG_IMAGE_SIZE(image)); pic->format=PIC_FORMAT_ARGB8888; pic->xsize=image.width; pic->ysize=image.height; if ( png_err=png_image_finish_read(&image, NULL/*background*/, pic->data, 0/*row_stride*/, NULL/*colormap*/),png_err != 0) { return 1; } else { myfree(pic->data); return 0; } } return 0; } //显示照片 int PHOTO_ShowPhoto (WIN_WindowStruct *base,char *name) { //解码图片 BITMAP_Struct bitmap={0}; WIN_PicStruct pic={0}; u8 ret=0; //判断图片格式 int str_len=strlen(name); char *p_str=&name[str_len-4]; //解码时显示提示,这个函数是阻塞的 if (strcmp (p_str,".jpg")==0) { decode_jpg_struct dec={0}; dec.bitmap=&bitmap;dec.name=(u8*)name; ret=WORKING_DoWork (base,"JPG解码中。。。",decode_jpg,&dec); if (ret==0) { pic.data=bitmap.buff; pic.xsize=bitmap.x_size; pic.ysize=bitmap.y_size; }else return -1; } else if (strcmp (p_str,".bmp")==0) { decode_bmp_struct dec={0}; dec.name=(u8 *)name; dec.bmp=(BMP_DecodeStruct *)&bitmap;//这两个结构体是一样的,直接强制转换 ret=WORKING_DoWork (base,"BMP解码中。。。",decode_bmp,&dec); if (ret==0) { pic.data=bitmap.buff; pic.xsize=bitmap.x_size; pic.ysize=bitmap.y_size; }else return -1; } else if(strcmp (p_str,".png")==0) { decode_png_struct dec={0}; dec.name=name; dec.pic=&pic; ret=WORKING_DoWork (base,"PNG解码中。。。",decode_png,&dec); if(ret==0) return -1; } WIN_PhotoStruct *photo=0; int x,y,xsize,ysize; if (base) { //WIN_GetWinPosOnLcd (base,&x,&y,&xsize,&ysize); x=0;y=0;xsize=base->x_size;ysize=base->y_size; } else { x=0;y=0;xsize=WIN_GetWinStruct()->lcd->getLcdSizeX();ysize=WIN_GetWinStruct()->lcd->getLcdSizeY(); } if (pic.xsizememData=bitmap.buff; return ret_; } //显示点阵图像 int PHOTO_ShowPic (WIN_WindowStruct *base,WIN_PicStruct *pic) { WIN_PhotoStruct *photo=0; int x,y,xsize,ysize; if (base) { //WIN_GetWinPosOnLcd (base,&x,&y,&xsize,&ysize); x=0;y=0;xsize=base->x_size;ysize=base->y_size; } else { x=0;y=0;xsize=WIN_GetWinStruct()->lcd->getLcdSizeX();ysize=WIN_GetWinStruct()->lcd->getLcdSizeY(); } if (pic->xsizexsize)/2;xsize=pic->xsize;} if (pic->ysizeysize)/2;ysize=pic->ysize;} //photo=WIN_CreatPhoto (0,0,x,y,xsize,ysize); photo=WIN_CreatPhoto (base,0,x,y,xsize,ysize); PHOTO_SetPic (photo,pic); photo->memData=mymalloc (photo->pic.xsize*photo->pic.ysize*2); if (photo->memData) { mymemcpy (photo->memData,photo->pic.data,photo->pic.xsize*photo->pic.ysize*2); photo->pic.data=photo->memData; photo->win.pic.data=photo->memData; } WIN_ShowWindow((WIN_WindowStruct *)photo); //int ret_= WIN_RunBlock ((WIN_WindowStruct *)photo); int ret_=0; return ret_; }