• jeremiah.helfer

    Hi
    I am having a very difficult time replacing the 'Rect' functions with c types. Is there someone on here with more experience that could walk me through it so I can do it in the future?

    I have attached one of the projects I am working on so I know what you do to fix it!

    def pil_to_ui(img):
        with io.BytesIO() as bIO:
            img.save(bIO, 'png')
            return ui.Image.from_data(bIO.getvalue())
        
    def ui_to_pil(img):
        return Image.open(io.BytesIO(img.to_png()))
        
    def crop_image(image):
        image = ui_to_pil(image)
        image_data = numpy.asarray(image)
        image_data_bw = image_data.max(axis=2)
        non_empty_columns = numpy.where(image_data_bw.max(axis=0)>0)[0]
        non_empty_rows = numpy.where(image_data_bw.max(axis=1)>0)[0]
        cropBox = (min(non_empty_rows), max(non_empty_rows), min(non_empty_columns), max(non_empty_columns))
        image_data_new = image_data[cropBox[0]:cropBox[1]+1, cropBox[2]:cropBox[3]+1 , :]
        new_image = pil_to_ui(Image.fromarray(image_data_new))
        return new_image
    
    class Pixel (scene.Rect):
        def __init__(self, x, y, w, h):
            scene.Rect.__init__(self, x, y, w, h)
            self.colors = [(0, 0, 0, 0)]
            
        def used(self):
            return len(self.colors) > 1 and self.colors[-1] != (0, 0, 0, 0)
            
        def undo(self):
            if len(self.colors) > 1:
                self.colors.pop()
    
    class PixelEditor(ui.View):
        def did_load(self):
            self.row = self.column = 16
            self.pixels = []
            self.pixel_path = []
            self.image_view = self.create_image_view()
            self.grid_layout = self.create_grid_layout()
            self.current_color = (0, 0, 0, 1)
            self.mode = 'pencil'
            self.auto_crop_image = False 
            
        def has_image(self):
            if self.pixel_path:
                if [p for p in self.pixel_path if p.used()]:
                    return True 
            return False 
    
        def set_image(self, image=None):
            image = image or self.create_new_image()
            self.image_view.image = self.superview['preview'].image = image
            
        def get_image(self):
            image = self.image_view.image
            if self.auto_crop_image:
                return crop_image(image)
            return image
            
        def add_history(self, pixel):
            self.pixel_path.append(pixel)
    
        def create_grid_image(self):
            s = self.width/self.row if self.row > self.column else self.height/self.column
            path = ui.Path.rect(0, 0, *self.frame[2:])
            with ui.ImageContext(*self.frame[2:]) as ctx:
                ui.set_color((0, 0, 0, 0))
                path.fill()
                path.line_width = 2
                for y in range(self.column):
                    for x in range(self.row):
                        pixel = Pixel(x*s, y*s, s, s)
                        path.append_path(ui.Path.rect(*pixel))
                        self.pixels.append(pixel)
                ui.set_color('gray')
                path.stroke()
                return ctx.get_image()
    
        def create_grid_layout(self):
            image_view = ui.ImageView(frame=self.bounds)
            image_view.image = self.create_grid_image()
            self.add_subview(image_view)
            return image_view
    
        def create_image_view(self):
            image_view = ui.ImageView(frame=self.bounds)
            image_view.image = self.create_new_image()
            self.add_subview(image_view)
            return image_view
    
        def create_new_image(self):
            path = ui.Path.rect(*self.frame)
            with ui.ImageContext(self.width, self.width) as ctx:
                ui.set_color((0, 0, 0, 0))
                path.fill()
                return ctx.get_image()
    
        def create_image_from_history(self):
            path = ui.Path.rect(*self.frame)
            with ui.ImageContext(self.width, self.height) as ctx:
                for pixel in self.pixel_path:
                    if not pixel.used():
                        continue 
                    ui.set_color(pixel.colors[-1])
                    pixel_path = ui.Path.rect(*pixel)
                    pixel_path.line_width = 0.5
                    pixel_path.fill()
                    pixel_path.stroke()
                img = ctx.get_image()
                return img
                
        def reset(self, row=None, column=None):
            self.row = row or self.row
            self.column = column or self.column
            self.pixels = []
            self.pixel_path = []
            self.grid_layout.image = self.create_grid_image()
            self.set_image()
    
        def undo(self):
            if self.pixel_path:
                pixel = self.pixel_path.pop()
                pixel.undo()
                self.set_image(self.create_image_from_history())
    
        def pencil(self, pixel):
            if pixel.colors[-1] != self.current_color:
                if self.current_color != (0, 0, 0, 0):
                    pixel.colors.append(self.current_color)
                    self.pixel_path.append(pixel)
                    old_img = self.image_view.image
                    path = ui.Path.rect(*pixel)
                    with ui.ImageContext(self.width, self.height) as ctx:
                        if old_img:
                            old_img.draw()
                        ui.set_color(self.current_color)
                        pixel_path = ui.Path.rect(*pixel)
                        pixel_path.line_width = 0.5
                        pixel_path.fill()
                        pixel_path.stroke()
                        self.set_image(ctx.get_image())
    
        def eraser(self, pixel):
            if pixel.used():
                pixel.colors.append((0, 0, 0, 0))
                self.pixel_path.append(pixel)
                img = self.create_image_from_history()
                self.set_image(self.create_image_from_history())
    
        def color_picker(self, pixel):
            self.current_color = pixel.colors[-1]
            self.superview['colors'].set_color(pixel.colors[-1])
    
        def action(self, touch):
            p = scene.Point(*touch.location)
            for pixel in self.pixels:
                if p in pixel:
                    eval('self.{}(pixel)'.format(self.mode))
    
        def touch_began(self, touch):
            self.action(touch)
    
        def touch_moved(self, touch):
            self.action(touch)
    
    class ColorView (ui.View):
        def did_load(self):
            self.color = {'r':0, 'g':0, 'b':0, 'a':1}
            for subview in self.subviews:
                self.init_action(subview)
    
        def init_action(self, subview):
            if hasattr(subview, 'action'):
                subview.action = self.choose_color if subview.name != 'clear' else self.clear_user_palette
            if hasattr(subview, 'subviews'):
                for sv in subview.subviews:
                    self.init_action(sv)
    
        def get_color(self):
            return tuple(self.color[i] for i in 'rgba')
    
        def set_color(self, color=None):
            color = color or self.get_color()
            for i, v in enumerate('rgba'):
                self[v].value = color[i]
                self.color[v] = color[i]
            rgb_to_hex = tuple(int(i*255) for i in color[:3])
            self['color_input'].text = ''.join('#{:02X}{:02X}{:02X}'.format(*rgb_to_hex))
            self['current_color'].background_color = color
            self.superview['editor'].current_color = color
    
        @ui.in_background
        def choose_color(self, sender):
            if sender.name in self.color:
                self.color[sender.name] = sender.value
                self.set_color()
            elif sender in self['palette'].subviews:
                self.set_color(sender.background_color)
            elif sender.name == 'color_input':
                try: 
                    c = sender.text if sender.text.startswith('#') else eval(sender.text)
                    v = ui.View(background_color=c)
                    self['color_input'].text = str(v.background_color)
                    self.set_color(v.background_color)
                except Exception as e:
                    console.hud_alert('Invalid Color', 'error')
    
    class ToolbarView (ui.View):
        def did_load(self):
            self.pixel_editor = self.superview['editor']
            for subview in self.subviews:
                self.init_actions(subview)
    
        def init_actions(self, subview):
            if hasattr(subview, 'action'):
                if hasattr(self, subview.name):
                    subview.action = eval('self.{}'.format(subview.name))
                else: 
                    subview.action = self.set_mode
            if hasattr(subview, 'subviews'):
                for sv in subview.subviews:
                    self.init_actions(sv)
                    
        def show_error(self):
            console.hud_alert('Editor has no image', 'error', 0.8)
            
        @ui.in_background       
        def trash(self, sender):
            if self.pixel_editor.has_image():
                msg = 'Are you sure you want to clear the pixel editor? Image will not be saved.'
                if console.alert('Trash', msg, 'Yes'):
                    self.pixel_editor.reset()
            else: 
                self.show_error()
                
        @ui.in_background
        def save(self, sender):
            if self.pixel_editor.has_image():
                image = self.pixel_editor.get_image()
                option = console.alert('Save Image', '', 'Camera Roll', 'New File', 'Copy image')
                if option == 1:
                    photos.save_image(image)
                    console.hud_alert('Saved to cameraroll')
                elif option == 2:
                    name = 'image_{}.png'
                    get_num = lambda x=1: get_num(x+1) if os.path.isfile(name.format(x)) else x
                    file_name = name.format(get_num())
                    with open(file_name, 'w') as f:
                        ui_to_pil(image).save(f, 'png')
                    console.hud_alert('Image saved as "{}"'.format(file_name))
                elif option == 3:
                    clipboard.set_image(image, format='png')
                    console.hud_alert('Copied')
            else: 
                self.show_error()
                
        def undo(self, sender):
            self.pixel_editor.undo()
                    
        @ui.in_background
        def preview(self, sender):
            if self.pixel_editor.has_image():
                v = ui.ImageView(frame=(100,400,512,512))
                v.image = self.pixel_editor.get_image()
                v.width, v.height = v.image.size
                v.present('popover', popover_location=(200, 275), hide_title_bar=True)
            else: 
                self.show_error()
                
        def crop(self, sender):
            if not self.pixel_editor.auto_crop_image:
                sender.background_color = '#4C4C4C'
                sender.tint_color = 'white'
                self.pixel_editor.auto_crop_image = True
            else: 
                sender.background_color = (0, 0, 0, 0)
                sender.tint_color = 'black'
                self.pixel_editor.auto_crop_image = False 
    
        @ui.in_background
        def pixels(self, sender):
            if self.pixel_editor.has_image():
                console.hud_alert("Can't chage size while editing.", "error")
                return 
            try: 
                size = eval(sender.text)
                row, column = (size if isinstance(size, tuple) else (size, size))
                self.pixel_editor.reset(row, column)
                self['pixels'].text = '{},{}'.format(row, column)
            except Exception as e:
                console.hud_alert('Invalid size', 'error', 0.8)
            
        def set_mode(self, sender):
            self.pixel_editor.mode = sender.name
            for b in self['tools'].subviews:
                b.background_color = tuple((0, 0, 0, 0))
            sender.background_color = '#4C4C4C'
    
    
    ui.load_view('pixel_editor').present(orientations=['portrait'])
    

    posted in Pythonista read more

Internal error.

Oops! Looks like something went wrong!