-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #757 from iceblu3710/BGImage_Kivy
Background image on working canvas
- Loading branch information
Showing
8 changed files
with
378 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import os | ||
from kivy.uix.gridlayout import GridLayout | ||
from UIElements.fileBrowser import FileBrowser | ||
from kivy.uix.popup import Popup | ||
from DataStructures.makesmithInitFuncs import MakesmithInitFuncs | ||
from UIElements.backgroundPickDlg import BackgroundPickDlg | ||
from kivy.core.image import Image as CoreImage | ||
from PIL import Image as PILImage | ||
from io import BytesIO | ||
import json | ||
|
||
graphicsExtensions = (".jpg", ".png", ".jp2",".webp",".pbm",".ppm",".pgm") | ||
|
||
|
||
class BackgroundMenu(GridLayout, MakesmithInitFuncs): | ||
|
||
def __init__(self, data, **kwargs): | ||
super(BackgroundMenu, self).__init__(**kwargs) | ||
self.data = data | ||
|
||
def updateAlignmentInConfig(self): | ||
self.data.config.set('Background Settings', 'manualReg', | ||
self.data.backgroundManualReg) | ||
self.data.config.set('Background Settings', 'backgroundfile', | ||
str(self.data.backgroundFile)) | ||
self.data.config.write() | ||
|
||
def openBackground(self): | ||
''' | ||
Open The Pop-up To Load A File | ||
Creates a new pop-up which can be used to open a file. | ||
''' | ||
# Starting path is either where the last opened file was | ||
# or the users home directory | ||
if not os.path.isdir(self.data.backgroundFile): | ||
startingPath = os.path.dirname(self.data.backgroundFile) | ||
else: | ||
# Don't go up a dir if the "backgroundFile" is a directory! | ||
startingPath = self.data.backgroundFile | ||
if startingPath is "": | ||
startingPath = os.path.expanduser('~') | ||
# We want to filter to show only files that ground control can open | ||
validFileTypes = graphicsExtensions | ||
validFileTypes = ['*{0}'.format(fileType) for fileType in validFileTypes] | ||
|
||
content = FileBrowser(select_string='Select', | ||
favorites=[(startingPath, 'Last Location')], | ||
path=startingPath, | ||
filters=validFileTypes, dirselect=False) | ||
content.bind(on_success=self.load, on_canceled=self.dismiss_popup, | ||
on_submit=self.load) | ||
self._popup = Popup(title="Select a file...", content=content, | ||
size_hint=(0.9, 0.9)) | ||
self._popup.open() | ||
|
||
def reloadBackground(self): | ||
self.processBackground() | ||
self.close() | ||
|
||
def processBackground(self): | ||
if self.data.backgroundFile == "" or os.path.isdir( | ||
self.data.backgroundFile): | ||
self.data.backgroundTexture = None | ||
self.data.backgroundManualReg = [] | ||
self.updateAlignmentInConfig() | ||
self.data.backgroundRedraw = True | ||
return | ||
else: | ||
img = PILImage.open(self.data.backgroundFile) | ||
img.thumbnail((1920, 1080), PILImage.ANTIALIAS) | ||
img = img.transpose(PILImage.FLIP_TOP_BOTTOM) | ||
imgBytes = BytesIO() | ||
img.save(imgBytes, format="png") | ||
imgBytes.seek(0) | ||
texture = CoreImage(imgBytes, ext="png").texture | ||
self.data.backgroundTexture = texture | ||
if self.data.backgroundManualReg: | ||
# Already have centers to use; just go on to warp_image | ||
self.warp_image() | ||
else: | ||
# Start the manual alignment process | ||
self.realignBackground() | ||
|
||
def realignBackground(self): | ||
content = BackgroundPickDlg(self.data) | ||
content.setUpData(self.data) | ||
content.close = self.close_PickDlg | ||
self._popup = Popup(title="Background PointPicker", content=content, | ||
size_hint=(0.9, 0.9)) | ||
self._popup.open() | ||
|
||
def close_PickDlg(self, instance): | ||
if instance.accepted: | ||
# Update manual image registration marks | ||
self.data.backgroundManualReg = instance.tex_coords | ||
# Save the data from the popup | ||
self.updateAlignmentInConfig() | ||
self.warp_image() | ||
self.dismiss_popup() | ||
self.close() | ||
|
||
def warp_image(self): | ||
self.data.backgroundRedraw = True | ||
|
||
def clear_background(self): | ||
''' | ||
Clear background | ||
''' | ||
self.data.backgroundFile = "" | ||
self.processBackground() | ||
self.close() | ||
|
||
def load(self, instance): | ||
''' | ||
Load A Background Image File from the file dialog | ||
Takes in a file path (from the pop-up filepicker | ||
or directory, if no file was picked) and processes it. | ||
''' | ||
if len(instance.selection) == 1: | ||
filename = instance.selection[0] | ||
else: | ||
# User pressed Submit without picking a file | ||
filename = instance.path | ||
# Save the file in the config... | ||
self.data.backgroundFile = filename | ||
# close the open file popup | ||
self.dismiss_popup() | ||
# new image loaded so clear manual alignment centers | ||
self.data.backgroundManualReg = [] | ||
# process it | ||
self.processBackground() | ||
# Close the menu, going back to the main page. | ||
self.close() | ||
|
||
def dismiss_popup(self, *args): | ||
''' | ||
Close The File Picker (cancel was pressed instead of OK). | ||
''' | ||
self._popup.dismiss() | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
from kivy.uix.gridlayout import GridLayout | ||
from kivy.properties import StringProperty, ListProperty, ObjectProperty | ||
from DataStructures.makesmithInitFuncs import MakesmithInitFuncs | ||
from kivy.vector import Vector | ||
|
||
|
||
class BackgroundPickDlg(GridLayout, MakesmithInitFuncs): | ||
instructionText = StringProperty("Drag bounding box to frame edges") | ||
texture = ObjectProperty(None) | ||
tex_coords = ListProperty([0, 0, 1, 0, 1, 1, 0, 1]) | ||
tex_selection = ListProperty([0, 0, 100, 0, 100, 100, 0, 100]) | ||
|
||
def __init__(self, data, **kwargs): | ||
super(BackgroundPickDlg, self).__init__(**kwargs) | ||
self.data = data | ||
# Load the texture | ||
self.texture = self.data.backgroundTexture | ||
# Window is not set up yet, wait for size.update | ||
self.imWidg.bind(size=self.update) | ||
self.update() | ||
|
||
def update(self, *args): | ||
if self.imWidg.size[0] is not 100 and self.imWidg.size[1] is not 100: | ||
# Widget is stable, update the textures bounds | ||
self.w, self.h = self.imWidg.size | ||
self.coeff_size = [self.w, self.h, self.w, self.h, | ||
self.w, self.h, self.w, self.h] | ||
# Place selection box | ||
self.tex_selection = [self.w * 0.2, self.h * 0.3, | ||
self.w * 0.9, self.h * 0.3, | ||
self.w * 0.9, self.h * 0.9, | ||
self.w * 0.2, self.h * 0.9] | ||
# Why??!!... | ||
self.resize_texture() | ||
self.reset_image() | ||
else: | ||
pass # Wait for widget to resize properly | ||
|
||
def reset_image(self): | ||
self.tex_coords = [0, 0, 1, 0, 1, 1, 0, 1] | ||
|
||
def resize_texture(self): | ||
coeffs = [] | ||
padOffx, padOffy = self.imWidg.pos | ||
i = 0 | ||
for (p, s) in zip(self.coeff_size, self.tex_selection): | ||
if i % 2: # y coord | ||
if p is not 0: | ||
coeffs.append(float(s - padOffy) / float(p)) | ||
else: | ||
coeffs.append(0.0 - padOffy) | ||
else: # x coord | ||
if p is not 0: | ||
coeffs.append(float(s - padOffx) / float(p)) | ||
else: | ||
coeffs.append(0.0 - padOffx) | ||
i += 1 | ||
self.tex_coords = coeffs | ||
|
||
def accept_texture(self): | ||
self.accepted = True | ||
self.close(self) | ||
|
||
def on_touch_down(self, touch): | ||
for i in range(4): | ||
x, y = self.tex_selection[i*2:i*2+2] | ||
if Vector(x - touch.x, y - touch.y).length() < 10: | ||
touch.grab(self) | ||
touch.ud['tex'] = i | ||
return True | ||
|
||
return super(BackgroundPickDlg, self).on_touch_down(touch) | ||
|
||
def on_touch_move(self, touch): | ||
if touch.grab_current is not self: | ||
return super(BackgroundPickDlg, self).on_touch_move(touch) | ||
|
||
tex = touch.ud.get('tex') | ||
|
||
if tex is not None: | ||
self.tex_selection[tex * 2] = touch.x | ||
self.tex_selection[tex * 2 + 1] = touch.y | ||
|
||
def on_touch_up(self, touch): | ||
if touch.grab_current is self: | ||
touch.ungrab(self) | ||
else: | ||
return super(BackgroundPickDlg, self).on_touch_up(touch) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.