Прикреплённый файл «2014-02-21-dumbedit.py»

Загрузка

   1 #!/usr/bin/env python
   2 # coding: utf
   3 '''
   4     «Ухудшенный графический редактор». Написать программу обработки изображений со следующими возможностями:
   5         Загрузка файла (нажатие клавиши "l", имя файла содержится в буфере обмена, в случае неудачи выводить предупреждение)
   6         Запись файла с тем же именем ("s")
   7         Рисование мышью (клавиша "d" + изменение курсора)
   8 
   9             <!> Нарисовать свой курсор 
  10         Поворот и изменение размера картинки (клавиша "r"): первая точка — центр вращения, затем поворот при нажатой кнопке (если нажата правая --- изменение размера). Курсор тоже менять 
  11 '''
  12 
  13 import pygame, sys, os
  14 from pygame.locals import *
  15 from math import *
  16 
  17 os.chdir(os.path.expanduser("~"))
  18 pygame.init()
  19 NoEvent = pygame.event.Event(NOEVENT)
  20 
  21 def fullcursor(spot, data, black='X', white='.', xor='o'):
  22     c = pygame.cursors.compile(data, black, white, xor)
  23     return ((len(data[0]),len(data)), spot) + c
  24 
  25 class BasicState:
  26     cursor = pygame.cursors.arrow 
  27 
  28     def __init__(self):
  29         pass
  30 
  31     def loop(self, event):
  32         if event.type == QUIT:
  33             game.exit = True
  34         elif event.type == KEYDOWN and event.unicode in u"Ff":
  35                 pygame.display.toggle_fullscreen()
  36         else:
  37             return event
  38         return NoEvent
  39     
  40     def redraw(self):
  41         game.screen.blit(game.back, (0,0))
  42         r = game.img.get_rect()
  43         r.center = game.screen.get_rect().center
  44         game.screen.blit(game.img, r)
  45 
  46 class LoadState(BasicState):
  47     cursor = fullcursor( (0,0), (
  48         " XXXXXXXXXXXXXXXXXXXXXX ",
  49         "XXXXXXXXXXXXXXXXXXXXXXXX",
  50         "XX      ...........   XX",
  51         "XX      ...........   XX",
  52         "XX      ...........   XX",
  53         "XX      ...........   XX",
  54         "XX      ...........   XX",
  55         "XX                    XX",
  56         "XX        oooo        XX",
  57         "XX       oooooo       XX",
  58         "XX      oooooooo      XX",
  59         "XX      oooooooo      XX",
  60         "XX      oooooooo      XX",
  61         "XX      oooooooo      XX",
  62         "XX       oooooo       XX",
  63         "XX        oooo        XX",
  64         "XX                    XX",
  65         "XX                    XX",
  66         "XX                    XX",
  67         "XX                    XX",
  68         "XX                    XX",
  69         "XX                    XX",
  70         "XXXXXXXXXXXXXXXXXXXXXXXX",
  71         " XXXXXXXXXXXXXXXXXXXXXX ",
  72     ))
  73     scrap = ""
  74 
  75     def __init__(self):
  76         BasicState.__init__(self)
  77         self.scrap = ""
  78 
  79     def action(self, text):
  80         try: 
  81             img = pygame.image.load(text)
  82             if not img: raise Error
  83         except:
  84             print >> sys.stderr, "Cannot load file '{}'".format(text)
  85             return False
  86         game.imgname, game.img = text, img
  87         return game.imgname
  88     
  89     def loop(self, event):
  90         event = BasicState.loop(self,event)
  91         if self.scrap:
  92             if self.action(self.scrap):
  93                 game.setstate(MainState)
  94                 return NoEvent
  95             else:
  96                 self.scrap = ""
  97         if event.type in (KEYDOWN, MOUSEBUTTONDOWN):
  98             game.setstate(MainState)
  99         elif event.type == MOUSEMOTION:
 100             text = pygame.scrap.get("TEXT").strip() 
 101             if text and text != self.scrap:
 102                 self.scrap = text
 103         else:
 104             return event
 105         return NoEvent
 106 
 107 class SaveState(LoadState):
 108     def __init__(self):
 109         LoadState.__init__(self)
 110         self.scrap = game.imgname
 111 
 112     def action(self, text):
 113         try: 
 114             pygame.image.save(game.screen, text)
 115             print >> sys.stderr, "Saving to '{}'".format(text)
 116         except:
 117             print >> sys.stderr, "Cannot write to file '{}'".format(text)
 118             return False
 119         game.imgname = text
 120         return game.imgname
 121 
 122 class DrawState(BasicState):
 123     cursor = pygame.cursors.broken_x
 124     def __init__(self):
 125         BasicState.__init__(self)
 126         self.pos=None
 127 
 128     def loop(self, event):
 129         event = BasicState.loop(self, event)
 130         if event.type == MOUSEMOTION:
 131             if self.pos:
 132                 pygame.draw.aaline(game.back, tan, self.pos, event.pos)
 133             self.pos = event.pos
 134         elif event.type == MOUSEBUTTONUP:
 135             game.setstate(MainState)
 136 
 137 class RotoState(BasicState):
 138     cursor = pygame.cursors.diamond
 139     def __init__(self):
 140         BasicState.__init__(self)
 141         self.pos = game.screen.get_rect().center
 142         self.back = game.screen
 143         self.img = game.screen.copy()
 144 
 145     def loop(self, event):
 146         events=[BasicState.loop(self, event)]+pygame.event.get()
 147         pos=self.pos
 148         for event in events:
 149             if event.type == MOUSEMOTION:
 150                 pos = event.pos
 151             elif event.type == MOUSEBUTTONUP:
 152                 pass
 153             elif event.type == MOUSEBUTTONDOWN:
 154                 game.setstate(MainState)
 155                 break
 156             else:
 157                 game.img = self.back
 158                 game.setstate(MainState)
 159                 return event
 160         if pos != self.pos:
 161             # TODO определить угол и расстояние от центра, а не x|y
 162             sz, rot = float(pos[0])/self.pos[0], float(pos[1])-self.pos[1]
 163             game.img = pygame.transform.rotozoom(self.img, rot, sz)
 164         return NoEvent
 165 
 166 class MainState(BasicState):
 167     def loop(self, event):
 168         event = BasicState.loop(self,event)
 169         if event.type == KEYDOWN:
 170             if event.unicode in u"Ll":
 171                 game.setstate(LoadState)
 172             elif event.unicode in u"Ss":
 173                 game.setstate(SaveState)
 174         elif event.type == MOUSEBUTTONDOWN:
 175             if event.button == 1:
 176                 game.setstate(DrawState)
 177             elif event.button == 3:
 178                 game.setstate(RotoState)
 179         else:
 180             return event
 181         return NoEvent
 182 
 183 class Game:
 184     def __init__(self):
 185         self.size = 800,600
 186         self.screen = pygame.display.set_mode(self.size)
 187         self.screen.fill((0,0,0))
 188         self.img = pygame.Surface((0,0))
 189         self.imgname = ""
 190         self.back = self.screen.copy()
 191         self.setstate(MainState)
 192         self.exit = False
 193 
 194     def setstate(self, state):
 195         self.state = state()
 196         pygame.mouse.set_cursor(*self.state.cursor)
 197 
 198 game = Game()
 199 
 200 pygame.scrap.init()
 201 pygame.scrap.set_mode(SCRAP_SELECTION)
 202 tan = pygame.Color("tan")
 203 imgname = ""
 204 state, pos = "base", (0,0)
 205 while not game.exit:
 206     event = pygame.event.wait()
 207     game.state.loop(event)
 208     game.state.redraw()
 209     pygame.display.flip()

Прикреплённые файлы

Для ссылки на прикреплённый файл в тексте страницы напишите attachment:имяфайла, как показано ниже в списке файлов. Не используйте URL из ссылки «[получить]», так как он чисто внутренний и может измениться.

Вам нельзя прикреплять файлы к этой странице.