Python Forum
Drawn line shift when that surface is copied to another in pygame
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Drawn line shift when that surface is copied to another in pygame
#1
Hi, I am currently making a pixel editor. And I was making the drawing tools, when I hit a problem. I was making a system where it will show how the canvas will look like before something is drawn (You will understand it better when you try the script out). The current way I am doing it is by copying the main surface(canvas) to another surface (pre_view) when the mouse is pressed, then it just draws the line on it, then resets the surface(recopying the main canvas). And when it the mouse is released that surface is copied to the main surface. But, the problem is, the line shifts a bit when it is copied to the main surface. I tried may things work on fixing it for many hours , but nothing.

Here is the code:

#------------------------ Import Bay ------------------------
import pygame
#------------------------ loading bay------------------------

pencil = pygame.image.load("Assets/tools/Pencil_tool/Pencil_tool_icon(Large)-export.png")
eraser = pygame.image.load("Assets/tools/Eraser_tool/Eraser_tool.png")



#------------------------ Variable Bay------------------------

version = "0.0.1"
running = True
current_tool = 0
colour = (255,255,255)


#------------------------Init Bay------------------------


pygame.init()


screen = pygame.display.set_mode((800,600))
canvas =  pygame.Surface((64, 64))
pre_view = pygame.Surface.copy(canvas)
pygame.display.set_caption("Pyxe")
icon = pygame.image.load("Assets/icons3.png")
pygame.display.set_icon(icon)
#------------------------Main Loop------------------------

screen.fill((62,53,70))
while running:
    
    mouse = pygame.mouse.get_pos()
    mouse_buttons = pygame.mouse.get_pressed()
    scaled_pos = (mouse[0] - 336, mouse[1] - 236 )
    
    
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            Dest =scaled_pos = (mouse[0] - 336, mouse[1] - 236 )
            
        if mouse_buttons[0] == 1:
            print("button 0 Active")
            pre_view = pygame.Surface.copy(canvas)
            pygame.draw.line(pre_view, colour ,Dest, scaled_pos)
            screen.blit(pre_view, (336,236))

            if event.type == pygame.MOUSEMOTION:
                pre_view == pygame.Surface.copy(canvas)
                
        
        if event.type == pygame.MOUSEBUTTONUP:
            canvas = pygame.Surface.copy(pre_view)
            screen.blit(canvas, (336, 236))
        
        if event.type == pygame.KEYDOWN:
            
            if event.key == pygame.K_s:
                pygame.image.save(pre_view, "canvas.png")
                print("saving......")
            

            
            
    
    
    screen.blit(pencil, (734, 60))
    screen.blit(eraser, (734, 120))
        
            
    
    pygame.display.update()
Thanks for helping Heart
Reply
#2
Quote:
            if event.type == pygame.MOUSEMOTION:
                pre_view == pygame.Surface.copy(canvas)

That's probably not what you wanted (comparison on the second line, instead of assignment). That said, I don't think it's the issue, as I still notice it after fixing it.

I'm not sure what the issue is. It looks like only the end point is shifting, and only a tiny amount, and it seems like it only sometimes does it. The only thing I can think of, is that the mouse moves a tiny bit between getting the last position and releasing the mouse button.

I think the way I'd try to fix it, is to maintain a start/end point in a list of operations, and recreate the surfaces based on the list of operations. But I also realize that isn't really fixing anything, and just trying to move on by using a different method of doing it haha
Leo_Red likes this post
Reply
#3
(Feb-05-2021, 07:13 PM)nilamo Wrote:
Quote:
            if event.type == pygame.MOUSEMOTION:
                pre_view == pygame.Surface.copy(canvas)

That's probably not what you wanted (comparison on the second line, instead of assignment). That said, I don't think it's the issue, as I still notice it after fixing it.

I'm not sure what the issue is. It looks like only the end point is shifting, and only a tiny amount, and it seems like it only sometimes does it. The only thing I can think of, is that the mouse moves a tiny bit between getting the last position and releasing the mouse button.

I think the way I'd try to fix it, is to maintain a start/end point in a list of operations, and recreate the surfaces based on the list of operations. But I also realize that isn't really fixing anything, and just trying to move on by using a different method of doing it haha
Hi, really thanks for helping Heart , I tried fixing it again today thinking that the pixels are really tiny and tiny mouse movements are the issue. So, I tried filtering the values out by getting all the values in a list and checking if the last numbers are not the same as others but it creates more problems. After much thinking, I think pygame itself is not the lib for making a pixel editor. It does not support zooming other than pygame.transform.scale(). It is a bit hard and messed up for making a zoom function. Does not come with layers out of the box (Not sure). So, after some more research, I came across pyglet, which has more features for image editing like animation, (Don't know about zooming), etc.. I am thinking of moving to pyglet now as I haven't done a lot in the project and will be easier to shift now. And maybe will be more helpful in the long term. Making a pixel editor is definitely possible in pygame as many have made it and that was why I used pygame. But, I want this to be my main project that I keep improving. After looking into the docs of pyglet, pygame is wayy easier to work with than pyglet (I think). I am not really giving up because of the issue with pygame that I am facing, but if I face an issue with this small thing, I am scared what will happen when I get into some big mechanics. What do you guys think about pyglet? Is this a mistake?

Thanks again Heart
Reply
#4
Pygame is a pretty barebones library, and there's definitely a lot of work involved to use it.
Pyglet is perhaps more geared to 3d games, and can fairly easily use shaders to take advantage of the gpu (which pygame cannot do).

I think you might have more luck using a 16x16 list/array as the "pixels", and then converting that to a surface as needed so it can be rendered at any size (allowing for zooming, or having it visible in multiple places [perhaps a zoomed in workspace, and an actual-size view next to it]). Or, you could try doing all your processing using Pillow, which is an incredible graphics package, again rendering it to a surface as needed.
Reply
#5
(Feb-08-2021, 04:21 PM)nilamo Wrote: Pygame is a pretty barebones library, and there's definitely a lot of work involved to use it.
Pyglet is perhaps more geared to 3d games, and can fairly easily use shaders to take advantage of the gpu (which pygame cannot do).

I think you might have more luck using a 16x16 list/array as the "pixels", and then converting that to a surface as needed so it can be rendered at any size (allowing for zooming, or having it visible in multiple places [perhaps a zoomed in workspace, and an actual-size view next to it]). Or, you could try doing all your processing using Pillow, which is an incredible graphics package, again rendering it to a surface as needed.

I will definitely try it out, I am sure it will fix the zoom problem. But, it still does not fix the shift problem. While trying to fix the issue, I found that mouse cords does somehow change when clicked. Maybe if I some how filter incorrect mouse readings, but I failed on doing it. On a side note, I found cocos2D which is based on pyglet, It does have some neat features and is also fast, but does not have any sort of documentation (It does, but it is really bad). I also found pycairo, but the same problem (Bad docs). It turns out tkinter has a lot of good feature for drawing. But, I did not choose that as i am trying to go for a pixel UI and not the generic OS UI. Still nothing that fits my needs. I want a good foundation for my project. Someone needs to make a great drawing lib in python LOL Is there any good drawing libs that I don't know of?

Thanks for helping Heart
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] Surface and rectangle in pygame Fabrizio_fg 6 2,211 May-27-2023, 09:15 AM
Last Post: Fabrizio_fg
  [PyGame] Pygame is treating blob_group as a surface, when I need it to treat it as a Sprite. Swagford 1 1,279 Jan-24-2023, 09:58 PM
Last Post: metulburr
  Coloring a surface with transparency Sandor 4 2,272 Jan-02-2022, 08:11 AM
Last Post: Sandor
  [PyGame] pygame.Surface.fill help Shemira 3 6,137 Nov-29-2019, 12:01 AM
Last Post: Shemira
  pygame and shift branching? MuntyScruntfundle 2 3,371 Feb-23-2019, 01:39 PM
Last Post: Windspar
  pygame.surface Graham 10 8,351 Nov-29-2018, 04:45 PM
Last Post: nilamo
  [PyGame] PLEASE HELP! TypeError: unsupported operand type(s) for +: 'pygame.Surface' and 'int' keyfive 1 5,244 Jun-19-2018, 01:20 PM
Last Post: volcano63

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020