One big image in canvas (need optimize) [closed] - javascript

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 8 years ago.
Improve this question
Hi i have one big image in the canvas it's 10 000~px x 10 000~ px. I need zoom in/out functions.
Offer me what technology i need use. Maybe i need split into smaller images like a google maps or something else..

There are several different ways you could address this issue.
Canvas does support the ability to change the size of an image on the fly by calling the drawImage function of the context object. There are several permutations of this function, the one you want is the one that takes two rectangles and the image object. The first rectangle will be the position of the image in x, y coordinates and the height and width of the area you want to copy to the canvas object. The second one will be the destination of the x and y coordinate of where you want to draw it on the canvas and the height and width.
Simple Example Code
context.drawImage(srcImage, 0, 0, 10000, 10000, 0, 0, 800, 800);
Now then in this example it will take the full image and reduce it down to a 800x800 image. Be careful when your sizing images because you can majorly distort the image if you don't keep the original aspect ration.
To make a Zoom feature you would then just change the source height and width which would in effect make it "zoom in". For example:
context.drawImage(srcImage, 1000, 1000, 2000, 2000, 0, 0, 800, 800);
In this example we would take the starting position of the image and move it to a different location in the source image. Then we would copy a 2000x2000 piece of the image into the same 800x800 canvas object.
Now then I do not recommend this approach because it is asking a lot of your users to download this large of a file. The next few solutions will depend on what scripting language you are using on the back end server. Most modern languages today have a decent support library to handle images so you can upload the image to the server and make it re-size it for your users. It might be helpful that the script also creates a re-sized cached version of the original image so that you can speed up server performance. For instance you could have the JavaScript start downloading the smallest version of the image and as the client request it download then next level of details needed. Again this could become very bandwidth intensive and slow for your end users.
The technique that I see being deployed in Google maps is they break the area you are viewing into blocks and then each block would download separately as you zoom in and out. You could replicate this technique with AJAX sending the server your current zoom level and image size. This is probably the more complicated version and would require a lot of work not only on the JavaScript but also on the server code that would handle the multiple request for image data which is beyond the scope of this answer.

Related

Canvas re-drawing gets stucked (performance-problem) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm about to create a GUI for my Raspi-Project. There is Nodejs running on the Raspi3 which runs a NodeJs-Server and a then it gets requested with Chromium in kiosk-mode.
One page of this GUI needs to visualize the states of 48x potentiometers, 12x buttons, 8x faders. The NodeJs-Server sends data (which was modified by user) via websocket to the client, which redraws the whole canvas. Works fine so far for a few elements:
works fine but with a slight delay if you look closer
Now the problem is, that whith the growing number of elements that need to be drawn, the performance drops down to unacceptable dalay-times.
works, but with a way too big dalay, as more elements are drawn
and those are not even the half of stuff that needs to be drawn.
I am confused now, because I read about how fast canvas is, before I decided to go that way, and if I deactivate all canvas-drawings and simply console.log() the data that comes in via websocket, it is fast like in realtime.
so what am I doning wrong? maybe there it would be better not to draw the whole canvas on every value-change but animate the canvas? maybe someone has experience on this?
Here is the code.. when you look into assets/js/menu.class.js, this is the file which generates the canvas. the function createControllerGUI(options) is called every via websocket, every time a value changes.
Canvas is quick, but still cpu intensive. Also speed changes with the platform a bit.
Your function does all the drawing operation each change. Those operations have strokes, fills, center aligned text and something more ( i did not look all in details ).
There are some ways in which you can optimize the drawing operations.
partial redrawing
maybe the most effective.
Keep track of where a widget is, keep track of what data changed from message to message and draw only the differences.
Use clearRect on the area occupied by the widget and redraw it. Do not touch the other pixels.
Unless an octopus is using the hardware, you will have 2 or 3 widget changing per frame at maximum.
stroke all at once.
Instead of stroking on a per widget basis, you can trace all the paths you need at once, using a moveTo to the new position when changing widget, and using a single stroke operation at the end of the loop.
caching
If you have some rotatory controls for example, you can draw them once on a small separate canvas, and use that canvas as a source image to be drawn at a different angle if you need to represent a rotated control.
DrawImage is often optimized with hardware operations while the single fill and stroke may not.
There are probably other ways, and you can look at high level libraries that can do this for you, exposing a widget logic instead of the low level drawing operations.

Performant ways of loading a huge image into the background of a D3 map [duplicate]

This question already has answers here:
Loading a huge image (5mb) into svg background leads to pixelation and performance issues
(2 answers)
Closed 7 years ago.
This question is concerning a previous one: Loading a huge image (5mb) into svg background leads to pixelation and performance issues
The image is ~5 MB big and 20000 x 11596 pixels.
Here I would like to know which alternatives there are to load a huge PNG image into the background. I already tried several things. Maybe I used them in the wrong way but at the end I need this image somehow in the zoom object of D3.js. That is most difficult part of all I believe. To load an image into the overall background is very simple indeed. But having it zoom- and drag-able is way harder. As you can see from the link above I already managed it but the performance was miserable.
So currently I have a "sometimes" running method with a svg background. But as you can see on the link above and visiting the website, it does not work right now. But the reason for this is I, believe, that the image resolution/size is too high. Some days ago it worked with the same code, very strange. So a svg background is no solution. And I already tested some other things:
loading an image to a img environment within the svg object - that did not show anything, I think the reason is because in svg you can just use image or xlink:href
loading html5 with canvas, showing the picture but not changing when zooming
loading image with CSS, did not work in the svg environment
So nothing helped or worked as intended. As I said I have some special requirements:
the image is about 5 MB big
the image is just another presentation of the map, so it shall just be loaded when the button on the bottom is clicked
at the end there are 3 images for each map a different, so it need to be possible to change it at runtime
the image shall be resized and dragged by the usual d3 events/mouse interactions
the map with the image shall be wit ha good performance, like the vector-based one
So the questions I have right now are:
which solution would be the best for my case
how to get it working with the zooming events
or maybe how to improve the current solution wth svg background
And I could also use tile images for sure. But I don't want zooming steps. I really would like to have a map that does not need to reload images if possible.
Thank you.
Btw here the image that shall be displayed: http://arda-maps.org/ages/pics/map/ages/firsthigh.png (needs some time for loading...)
As in Loading a huge image (5mb) into svg background leads to pixelation and performance issues there does not seen to be a solution. Just lower the size and it works in Firefox and Chrome.

Most appropriate layout for (Computer) Network Diagram [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
I'm trying to develop a HTML/JS based "(computer) network diagram". By this I mean boxes linking to other boxes, and more importantly, boxes contained inside the bounds of other boxes.
Simplified Use Case - to explain the layout requirements
The use case is VPC (huge box) with AZ inside (2 or 3 big boxes stacked next to each other), and subnets inside each of those (boxes stacked on top of each other), and EC2s inside that (lots of small boxes next to each other).
While I've tried a number of methods (see below) I haven't found a suitable layout for my diagram and am wondering if my needs are so unique that I need to roll my own.
What I want help with...
I'm wondering if I'm missing something obvious in my research (in terms of options for a HTML5/JS solution)
Am I taking the right approach looking for a framework or are these requirements too special?
Should I consider writing my own layout (or does someone have a good idea for a good layout to start with)
Is there a framework that does visual grouping well (e.g draw a big box that contains smaller boxes, maybe a few levels deep)
My Research:
Webcola (can use with d3) http://marvl.infotech.monash.edu/webcola/
D3 http://d3js.org/
JointJS http://www.jointjs.com/demos/devs
Webcola
I originally tried Webcola as the following example seemed the most promising:
http://marvl.infotech.monash.edu/webcola/examples/smallgroups.html
I found the documentation to be lacking, a few of the links are dead, and when trying to combine the "Layout with hierarchical grouping" with "Alignment constraints with guidelines" the page failed to load.
D3.js
This appears to have lots of documentation, although I couldn't find a single example that came close to what I wanted to build.
https://github.com/mbostock/d3/wiki/Pack-Layout
Pack Layout seems the closest, with nesting used to represent the hierarchy.
The problem with this method is the size of each node is not uniform (I can just set them all to 1) and the example uses circles (this appears to be a hard rule with this layout, I think).
JointJS
http://www.jointjs.com/demos/devs
This appears to have a nice example with what appears to be a group and inputs/outputs (although the node can escape the bounds of its parent which isn't ideal.
If I did undersand your problem well, it can be done with HTML/CSS only :
the VPC div (container) is in position relative the and float left
position relative too inside an again float left with clear left if
you want to create another line
Beware of the width of the div

creating an HTML5 piano roll editor [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am creating a piano roll like interface, one like you might find in a DAW such as ableton, that looks something like this http://www.abletonlife.com/wp-content/uploads/2010/04/midi-track-big.jpg . The grid represents a canvas to draw in notes to be played, the red squares being the notes to play. You double click on an empty space to create a new note, and you can drag the edges to change the length of the note.
I am new to web dev so I am having a bit of trouble seeing what the right architecture for this might be. With my limited knowledge, the following are the architectures I can think of.
1) Rows of horizontal flex-boxes.
display: box;
box-orient: horizontal;
box-flex: 1;
Something like this, http://jsfiddle.net/ZgzNw/.
Pros:
When resizing the browser window, the browser will automatically
handle resizing of the notes and therefore the grid. Resizing of divs/notes also handled easily for zooming in and out and changing quantization values.
All notes in all positions already exist, when double clicking to "create" a new note, all you have to do is change the css for that note (to be red) etc.
Cons:
Since there is a div for every space in the grid, even empty spaces where there is no note to be played, there will be a lot of divs. Can the browser handle thousands of divs? As an extreme example if there is a 32nd note quantization, a song of 200BPM would have 50 measures per minute, take a 10 minutes song, that would be 500 measures. Going back to the jsfiddle example above and setting measures=500 and quant=32, I get the following error in the Chrome Developer tools console after a few seconds "Uncaught RangeError: Maximum call stack size exceeded". This is when creating the divs in that bit of javascript, If I lower the number to around 300 it is able to create the divs, but things become laggy.
2) Create the grid using divs of width=1px for the vertical lines of the grid. Create new note divs on the fly, position them manually (with position: float?) based on the position of the mouse click.
Pros:
Only have a divs for actual note that are on, so don't have the con of method 1) being an issue
Cons:
Have to manually compute everything, Where to place newly created note, zooming in/out means repositioning vertical markers for grids, and calculating new sizes for note divs. This was mostly handled automatically in the method 1.
I'm sure there are a lot more architectures and pros/cons to the two methods I describe, but I've never created any web applications and the extent of my web-dev experience is the tutorials I've done over the last 2 weeks to teach myself.
My question I guess is what is the best architecture for creating this piano roll interface I am describing? Specifically the UI representation, not the backing model.
I would create a simple model (probably just a multi-dimensional array) to contain the representation of the score, where each array item represented a note at a point in time. From the model, you can then draw/redraw accordingly. You could also perform operations like time shifts, quantizing, thinning, etc. by modifying the arrays.
Can the browser handle thousands of divs?
A few thousand, yes, maybe more--maybe even a lot more--but results will greatly vary by browser, by computer, even by the way they are positioned (floats tend to be slower than absolute positioning, for example, because the browser has more to calculate).
Instead, I would research using a canvas and draw/redraw based on your underlying model. You can detect events on the whole canvas, and depending on coordinates, easily map the event to the note(s) to which it corresponds.
KineticJS has some cool examples using a canvas
I would use a background image to represent tracks and measures, and one div for each note. It is not necessary to keep all notes as div’s in the browser, it would work better only to have the div’s for the visible up to 10 measures.
Imho, this should be done fixed-width, and there should not be any resizing of the piano roll at all. So you can use calculation of pixels. I don’t think this will work without making use of Javascript heavily.

Free Open Source In-browser image editors [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
I'm looking for a in-browser image editing solution to integrate with my project: http://code.google.com/p/django-ray/
I got it working with Pixlr quite easily and the editor is fantastic .. however it's a hosted service, which means I must be connected to Internet for it to work ..
Is there any other solution like Pixlr but that are not hosted service ?
Updates
Editors found so far:
AIE: http://www.ajax-image-editor.com/ (feels clunkier than Gimp..)
Pixidou: http://github.com/asvinb/pixidou (no working demo found..)
And a good list of editors that are hosted: http://www.lifeclever.com/10-free-web-based-alternatives-to-photoshop/
Adobe has discontinued the creativeSDK Image Editor UI
This solution appears to no longer be viable. Sorry :(
Adobe deprecation announcement
Previous answer:
Aviary (acquired by Adobe) offers a free feature-rich on-page editor called Feather. It is hosted, however, in that you must perform a GET to retrieve the final full-size edited image. It's features include:
enhance (new): Autocorrect your photo with one of four basic enhancements.
effects (new): Choose from a variety of effects and filters for your photo.
stickers: Choose from a variety of stickers you can resize and place on your photo.
orientation (new): Rotate and flip your photo in one tool.
resize: Resize the image using width and height number fields.
crop: Crop a portion of your photo. Add presets via API. Fixed-pixel cropPresets perform a resize when applied (new).
brightness: Adjust the overall image brightness.
contrast: Adjust the overall image contrast.
saturation: Adjust the overall image saturation.
sharpness (new): Blur or sharpen the overall image in one tool.
draw: Add doodle overlays with a brush.
text: Add custom, resizable text.
redeye: Remove redeye from your photo with a brush.
whiten: Whiten teeth with a brush. (Not supported in IE7-IE8)
blemish: Remove skin blemishes with a brush.
I'm currently integrating it in a site and there are a few gotchas (they might be my fault.) I can't ever get it to perform a POST callback to my URL with the finished image URL, so instead I use the objects .onSave handler which provides the same info. Also, in current chrome/firefox, there is a security exception when Feather modifies canvas data directly from your site. So instead provide the url option (causing Feather to request the image at that URL and then provide it back to the widget on your page.)
I've just been looking at JCrop, a JQuery plugin which looks great and works beautifully - on most modern browsers, so check your target platform is supported.
You can see it in action and download the scripts from here
http://deepliquid.com/content/Jcrop.html
and you will need the JQuery script framework, available from jquery.com
It's all free and Open Source, so you can customise it as much as you like.
Rob

Categories

Resources