📄 image.cpp
字号:
db_var = 0; else db_nr = -1; } abstract_character *db_abstract_char = db_nr == -1 ? NULL : &char_db.get_shape( db_nr, db_var ); for ( int h = 0; h < 2; h++ ) { if ( !h && db_nr == -1 ) continue; const abstract_character *ac = h ? abstract_char : db_abstract_char; for ( int i = 0; i < static_cast< int >( ac->aspv.size() ); i++ ) { for ( list< int >::const_iterator j = ac->aspv[i].acl.begin(); j != ac->aspv[i].acl.end(); ++j ) { const abstract_connection &acon = ac->acv[*j]; if ( acon.singular_point_1 == i ) { bool first=true; int x1 = x0 + qRound( ac->aspv[acon.singular_point_1].x * one ); int y1 = y0 - qRound( ac->aspv[acon.singular_point_1].y * one ); int x2 = x0 + qRound( ac->aspv[acon.singular_point_2].x * one ); int y2 = y0 - qRound( ac->aspv[acon.singular_point_2].y * one ); painter.moveTo( x1, y1 ); for ( list< point<float> >::const_iterator k = acon.polyline.begin(); k != acon.polyline.end(); ++k ) { int x = x0+qRound( k->x * one ); int y = y0-qRound( k->y * one ); if ( first ) { setFillParameter( painter, pens[h][2] ); if ( draw_flags & draw_guessed_lines ) painter.lineTo( x, y ); else painter.moveTo( x, y ); painter.setPen( pens[h][1] ); first = false; } else painter.lineTo( x, y ); drawFilledCircleFast( painter, x, y, diameter ); } painter.setPen( pens[h][2] ); if ( draw_flags & draw_guessed_lines ) painter.lineTo( x2, y2 ); drawFilledCircle( painter, pens[h][0], x2, y2, 3*diameter/2, false ); } } int x=x0+qRound( ac->aspv[i].x * one ); int y=y0-qRound( ac->aspv[i].y * one ); drawFilledCircle( painter, pens[h][0], x, y, 3*diameter/2, false ); } } // 匹配状态 if ( draw_flags & draw_abstract_matching && db_abstract_char ) { match_debug_info mdi; db_abstract_char->match( *abstract_char, FLT_MAX, &mdi ); QPen red_pen( QColor( "red" ), pen_size/2 ), green_pen( QColor( "green" ), pen_size/2 ); for ( list< match_debug_info::square >::const_iterator i = mdi.square_begin(); i != mdi.square_end(); ++i ) { painter.setPen( i->color ? green_pen : red_pen ); painter.moveTo( x0 + qRound( i->data[3].x * one ), y0 - qRound( i->data[3].y * one ) ); for ( int j = 0; j < 4; j++ ) painter.lineTo( x0+qRound( i->data[j].x*one ), y0-qRound( i->data[j].y*one ) ); } setFillParameter( painter, QPen( QColor( "blue" ), pen_size/2 ) ); for ( list< match_debug_info::line >::const_iterator i = mdi.line_begin(); i != mdi.line_end(); ++i ) { painter.drawLine( x0 + qRound( i->data[0].x * one ), y0 - qRound( i->data[0].y * one ), x0 + qRound( i->data[1].x * one ), y0 - qRound( i->data[1].y * one ) ); } } return; } pix.fill( QColor( "grey" ) ); if ( scan.width() != 0 ) // 如果没有图像,什么也不作 { QPainter painter( &pix ); // 绘制源字符 painter.scale( factor, factor ); if ( draw_flags & draw_bw ) painter.drawImage( 0, 0, scan_bw ); else painter.drawImage( 0, 0, scan ); painter.resetXForm(); // 绘制孤立区域 if ( draw_flags & draw_singular_regions ) { QColor color( "navy" ); QBrush br( color ); painter.setPen( color ); painter.setBrush( br ); for ( int y = 0; y < scan.height(); y++ ) for ( int x = 0; x < scan.width(); x++ ) if ( segimage->get_pixel( x, y ).is_filled ) painter.drawRect( qRound( x*factor ), qRound( y*factor ), qRound( factor ), qRound( factor ) ); } // 绘制网格 if ( draw_flags & draw_grid ) { painter.setPen( gray ); for ( int x = 0; x <= scan.width(); x++ ) { int x_int = qRound( x*factor ); painter.drawLine( x_int, 0, x_int, qRound( scan.height()*factor ) ); } for ( int y = 0; y <= scan.height(); y++ ) { int y_int = qRound( y*factor ); painter.drawLine( 0, y_int, qRound( scan.width()*factor ), y_int ); } } // 绘制边界列表 if ( draw_flags & draw_border_lists ) { QColor color( "yellow" ); painter.setBrush( color ); painter.setPen( QPen( color, pen_size ) ); for ( int i = 0; i < static_cast<int>( bl.size() ); i++ ) { if ( border_list_number == 0 || border_list_number == i+1 ) for ( vector< qlist< Segimage::point > >::iterator n = bl[i].begin(); n != bl[i].end(); n++ ) { bool first = true; ringlist_iterator< Segimage::point > m( *n ); for ( int o = n->size() + 1; o > 0; ++m, o-- ) { int x = qRound( m->x*factor + factor/2 ); int y = qRound( m->y*factor + factor/2 ); if ( first ) { painter.moveTo( x, y ); first = false; } else painter.lineTo( x, y ); drawFilledCircleFast( painter, x, y, diameter ); } } } } // 绘制边界角度 if ( draw_flags & draw_border_angles ) { QPen green_pen( QColor( "green" ), pen_size ), yellow_pen( QColor( "yellow" ), pen_size ), red_pen( QColor( "red" ), pen_size ); for ( int i = 0; i < static_cast<int>( bl.size() ); i++ ) { if ( border_list_number == 0 || border_list_number == i+1 ) for ( vector< qlist< Segimage::point > >::iterator n = bl[i].begin(); n != bl[i].end(); n++ ) { ringlist_iterator< Segimage::point > m( *n ); for ( int o = n->size()+1; o > 0; ++m, o-- ) { QPen pen = green_pen; float angle = m->ang; if ( m->oang != 0 ) { if ( draw_flags & draw_border_angles_smooth ) { if ( m->good_smoothed ) pen = yellow_pen; else pen = red_pen; } else angle = m->oang; } int x = qRound( m->x * factor + factor/2 ); int y = qRound( m->y * factor + factor/2 ); double length = avg_line_thickness / 3.5; int dest_x = x + static_cast<int>( cos( -angle )*length * factor ); int dest_y = y + static_cast<int>( sin( -angle )*length * factor ); drawFilledCircle( painter, pen, x, y, diameter, false ); painter.drawLine( x, y, dest_x, dest_y ); if ( m->dang < 0 ) drawFilledCircleFast( painter, dest_x, dest_y, diameter ); } } } } // 绘制交叉区域 if ( draw_flags & draw_cross_sections ) { QColor color( "HotPink" ); painter.setBrush( color ); painter.setPen( QPen( color, pen_size ) ); int cs_count = 0; for ( list<Segimage::cs_sequence>::iterator i = cssl.begin(); i != cssl.end(); ++i ) for ( list<Segimage::point *>::iterator j = i->begin(); j != i->end(); ++j ) { int x = qRound( ( *j )->x*factor + factor/2 ); int y = qRound( ( *j )->y*factor + factor/2 ); int ox = qRound( ( *j )->opp->x*factor + factor/2 ); int oy = qRound( ( *j )->opp->y*factor + factor/2 ); drawFilledCircleFast( painter, x, y, diameter ); painter.drawLine( x, y, ox, oy ); // 标记特定的 cs if ( mark_cs == cs_count ) { painter.save(); QColor color( "green" ); painter.setBrush( color ); painter.setPen( QPen( color, pen_size*3 ) ); drawFilledCircleFast( painter, x, y, diameter ); painter.drawLine( x, y, ox, oy ); painter.restore(); } cs_count++; } } // 绘制骨架 if ( draw_flags & draw_skeleton ) { QPen green_pen( green, pen_size ), red_pen( red, pen_size ); for ( list< Segimage::singularpoint >::iterator i = spl.begin(); i != spl.end(); ++i ) { for ( list< Segimage::cs_sequence_start >::iterator j = i->cs_sequences.begin(); j != i->cs_sequences.end(); ++j ) { int x = qRound( i->x*factor + factor/2.0 ); int y = qRound( i->y*factor + factor/2.0 ); painter.moveTo( x, y ); Segimage::cs_sequence::iterator k; if ( j->is_start ) k = j->sequence->begin(); else { k = j->sequence->end(); k--; } while( k != ( j->is_start ? j->sequence->end() : j->sequence->begin() ) ) { x = qRound( ( ( *k )->x + ( *k )->opp->x )/2.0 * factor + factor/2.0 ); y = qRound( ( ( *k )->y + ( *k )->opp->y )/2.0 * factor + factor/2.0 ); drawFilledCircle( painter, red_pen, x, y, diameter, false ); painter.lineTo( x, y ); j->is_start ? ++k : --k; } } setFillParameter( painter, QPen( QColor( "cyan" ), pen_size ) ); drawFilledCircleFast( painter, qRound( i->x*factor + factor/2.0 ), qRound( i->y*factor + factor/2.0 ), diameter ); } } // 绘制骨架点的方向向量 if ( skeleton != NULL && ( draw_flags & draw_directions ) ) { QPen green_pen( green, pen_size ), red_pen( red, pen_size ); for ( list<singular_point>::iterator i = skeleton->spl.begin(); i != skeleton->spl.end(); ++i ) { for ( list<inner_sequence_start>::iterator j = i->sequences.begin(); j != i->sequences.end(); ++j ) { int x=qRound( i->x*factor+factor/2.0 ); int y=qRound( i->y*factor+factor/2.0 ); painter.moveTo( x, y ); inner_sequence::iterator k; if ( j->is_start ) k=j->sequence->begin(); else { k=j->sequence->end(); k--; } while( k != ( j->is_start?j->sequence->end():j->sequence->begin() ) ) { x=qRound( k->x*factor+factor/2.0 ); y=qRound( k->y*factor+factor/2.0 ); painter.moveTo( x, y ); drawFilledCircle( painter, red_pen, x, y, diameter, false ); painter.setPen( green_pen ); painter.lineTo( qRound( x + ( factor-1+pen_size )/3.0 * cos( k->direction ) ), qRound( y + ( factor-1+pen_size )/3.0 * sin( -k->direction ) ) ); j->is_start ? ++k : --k; } } } } // 绘制多边形骨架 if ( skeleton != NULL && ( draw_flags & draw_polygon_skeleton ) ) { QPen yellow_pen( QColor( "yellow" ), pen_size ), aquamarine_pen( QColor( "aquamarine" ), pen_size ), aquamarine_pen_dashed( QColor( "aquamarine" ), pen_size, DashLine ); for ( list<singular_point>::iterator i=skeleton->spl.begin(); i != skeleton->spl.end(); ++i ) { for ( list<inner_sequence_start>::iterator j = i->sequences.begin(); j != i->sequences.end(); ++j ) { if ( j->is_start ) { bool first = true; int x1 = qRound( i->x*factor + factor/2.0 ); int y1 = qRound( i->y*factor + factor/2.0 ); int x2 = qRound( j->connect->point2->x*factor + factor/2.0 ); int y2 = qRound( j->connect->point2->y*factor + factor/2.0 ); painter.moveTo( x1, y1 ); list<skeleton_sequence>::iterator k = j->connect->sseql.begin(); for ( ; k != j->connect->sseql.end(); ++k ) { int x1 = qRound( k->first->aligned_x*factor + factor/2.0 ); int y1 = qRound( k->first->aligned_y*factor + factor/2.0 ); int x2 = qRound( k->last->aligned_x*factor + factor/2.0 ); int y2 = qRound( k->last->aligned_y*factor + factor/2.0 ); if ( first ) { setFillParameter( painter, aquamarine_pen_dashed ); if ( draw_flags & draw_guessed_lines ) painter.lineTo( x1, y1 ); painter.setPen( aquamarine_pen ); first=false; } drawFilledCircleFast( painter, x1, y1, diameter ); drawFilledCircleFast( painter, x2, y2, diameter ); painter.drawLine( x1, y1, x2, y2 ); } painter.setPen( aquamarine_pen_dashed ); if ( draw_flags & draw_guessed_lines ) painter.lineTo( x2, y2 ); drawFilledCircle( painter, yellow_pen, x2, y2, 3*diameter/2, false ); } } int x = qRound( i->x*factor + factor/2.0 ); int y = qRound( i->y*factor + factor/2.0 ); drawFilledCircle( painter, yellow_pen, x, y, 3*diameter/2, false ); } } }}// 绘制填充圆void Image::drawFilledCircle( QPainter &p, const QPen &pen, int x, int y, int diameter, bool save_state ){ if ( save_state ) p.save(); setFillParameter( p, pen ); drawFilledCircleFast( p, x, y, diameter ); if ( save_state ) p.restore();}// 设置绘制标识void Image::set_draw_flag( drawing_flags flag, bool state ){ if ( state ) draw_flags |= flag; else draw_flags &= ~flag; repaint();}// 鼠标移动事件void Image::mouseMoveEvent( QMouseEvent *e ){ if ( scan.width() != 0 ) // 没有图像,则不作任何操作 { float factor = get_ratio(); if ( factor > 0 ) { int x = qRound( e->x() / factor ); int y = qRound( e->y() / factor ); app->slotStatusMsg( QString( "Position ( x, y ): %1, %2" ).arg( x ).arg( y ) ); } }}// 按键事件void Image::keyPressEvent( QKeyEvent *e ){ switch ( e->key() ) { case Key_Print: makeSnapshot(); // 写入图像的快照 break; default: QKeyEvent accel_event( QEvent::Accel, e->key(), e->ascii(), 0 ); QApplication::sendEvent( app, &accel_event ); QApplication::sendEvent( app, e ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -