Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Edycja zaznaczonego obszaru na canvasie i Historia

Ostatnio zmodyfikowano dzisiaj: 4h » 6 min
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
Edycja zaznaczonego obszaru na canvasie i Historia
» 2026-03-19 15:23:15
Cześć.
Tworzę program do edycji grafiki. Mam problem z  nałożeniem efektu na zaznaczony obszar obrazu i zapisaniem tego w historii programu.

Wymyśliłem, że można to zrobić w ten sposób tylko nie wiem jak to napisać kodem.
-zrobienie kopii zapasowej zaznaczonego obszaru
-Nalozenie efektu na zaznaczony obszar
-Wklejenie zaznaczenia do obrazu
-zapisanie historii
-Przywrocenie obrazu sprzed zapisu historii(żeby zaznaczenie było możliwe do przesunięcia)

Zapisuje zdarzenie historii w następujący sposób:
C/C++
void History::saveStep() {
   
   
// if we are not at the end of the history, we need to erase the future steps
   
if( _currentStep + 1 <( int )( _steps.size() ) ) {
       
_steps.erase( _steps.begin() +( _currentStep + 1 ), _steps.end() );
   
}
   
   
DebugLog( L"History::saveStep: currentStep=" + std::to_wstring( _currentStep ) + L", stepsCount=" + std::to_wstring( _steps.size() ) );
   
   
// save the current state of the animations
   
std::shared_ptr < Step > step = std::make_shared < Step >();
   
for( auto & animation: animations ) {
       
std::shared_ptr < Animation > copied_animation = std::make_shared < Animation >();
       
for( auto & frame: animation->_frames ) {
           
std::shared_ptr < Frame > copied_frame = std::make_shared < Frame >();
           
for( auto & layer: frame->_layers ) {
               
std::shared_ptr < Layer > copied_layer = std::make_shared < Layer >( layer );
               
copied_frame->addLayer( copied_layer );
           
}
           
copied_animation->addFrame( copied_frame );
       
}
       
step->_animations.push_back( copied_animation );
   
}
   
   
_steps.push_back( step );
   
_currentStep++;
}

Nałożenie efektu na zaznaczenie:
C/C++
void Dialog_Brightness_Contrast::setTheFilter() {
   
   
if( selection->_state != SelectionState::None ) {
       
selection->resizeImage(); // update, żeby nie nadpisywać oryginalnego obrazu zaznaczenia
       
set_brightness( * selection->_resizedImage, _brightness_slider->getValue() );
       
set_contrast( * selection->_resizedImage, _contrast_slider->getValue() );
   
} else {
       
// edit all layers of the current frame
       
_edited_layers.clear();
       
for( auto & org: _original_layers ) {
           
_edited_layers.push_back( std::make_shared < Layer >( org ) );
       
}
       
       
set_brightness( _edited_layers[ getCurrentAnimation()->getCurrentLayerID() ]->_image, _brightness_slider->getValue() );
       
set_contrast( _edited_layers[ getCurrentAnimation()->getCurrentLayerID() ]->_image, _contrast_slider->getValue() );
       
       
getCurrentAnimation()->getCurrentFrame()->_layers.clear();
       
getCurrentAnimation()->getCurrentFrame()->_layers = _edited_layers;
   
}
   
}

zapisanie efektu po wykonanej akcji
C/C++
Dialog_Brightness_Contrast::~Dialog_Brightness_Contrast() {
   
   
if( Dialog_Brightness_Contrast::_state == BrightnessContrastState::Idle ) {
       
_brightness_slider->setValue( 0 );
       
_contrast_slider->setValue( 0 );
       
setTheFilter();
       
       
getCurrentAnimation()->getCurrentFrame()->_layers.clear();
       
getCurrentAnimation()->getCurrentFrame()->_layers = _edited_layers;
       
layers_panel->loadLayersFromCurrentFrame();
   
} else {
       
// is Edited
       
history->saveStep();
   
}
   
}
P-183954
tBane
Temat założony przez niniejszego użytkownika
» 2026-03-19 15:39:45
Dobra. Chyba mam rozwiązanie. Co o tym myślicie?

C/C++
Dialog_Brightness_Contrast::~Dialog_Brightness_Contrast() {
   
   
if( Dialog_Brightness_Contrast::_state == BrightnessContrastState::Idle ) {
       
_brightness_slider->setValue( 0 );
       
_contrast_slider->setValue( 0 );
       
setTheFilter();
       
       
getCurrentAnimation()->getCurrentFrame()->_layers.clear();
       
getCurrentAnimation()->getCurrentFrame()->_layers = _edited_layers;
       
layers_panel->loadLayersFromCurrentFrame();
   
} else {
       
// is Edited
       
if( selection->_state != SelectionState::None ) {
           
sf::Image orginalImage = getCurrentAnimation()->getCurrentLayer()->_image;
           
pasteImageWithMask( getCurrentAnimation()->getCurrentLayer()->_image, * selection->_resizedImage, selection->_resizedRect.position.x, selection->_resizedRect.position.y, * selection->_resizedMaskImage,( toolbar->_option_transparency->_checkbox->_value == 0 ) ? sf::Color::Transparent
                : toolbar->_second_color->_color );
           
history->saveStep();
           
getCurrentAnimation()->getCurrentLayer()->_image = orginalImage;
       
}
       
else {
           
history->saveStep();
       
}
    }
}
P-183955
pekfos
» 2026-03-19 16:07:55
Destruktor nie jest dobrym miejscem na taki kod. Jeśli już musisz, to zapakuj całość w try catch, choćby tak
C/C++
Dialog_Brightness_Contrast::~Dialog_Brightness_Contrast() {
   
try
   
{
       
// tamten kod
   
}
   
catch( ... )
   
{
    }
}
No chyba że i tak nigdzie w programie nie obsługujesz wyjątków, wtedy bez różnicy czy program wywali się wcześniej czy później.
P-183957
tBane
Temat założony przez niniejszego użytkownika
» 2026-03-19 16:30:56
Nigdzie nie obsługuję wyjątków. Dlaczego dobrze napisany program miałby się wywalić?
P-183958
« 1 »
  Strona 1 z 1