I am trying to make an old TV static type effect in P5.js, and although I am able to make the effect work, the frame rate is quite low.
My approach is the following:
Loop through each pixel
Set the stroke to a random value
Call the point() function to paint the pixel
Initially, I was doing this in the draw function directly but it was very slow. I was getting less than 1 frame a second. So I switch to the following paint buffer approach:
const SCREEN_WIDTH = 480
const SCREEN_HEIGHT = 480
var ScreenBuffer;
function setup(){
createCanvas(SCREEN_WIDTH, SCREEN_HEIGHT);
ScreenBuffer = createGraphics(SCREEN_WIDTH,SCREEN_HEIGHT);
}
function draw(){
paintBuffer();
image(ScreenBuffer,0,0);
}
function paintBuffer(){
console.log("Painting Buffer")
for(var x = 0; x< SCREEN_WIDTH; x++){
for(var y = 0; y< SCREEN_HEIGHT; y++){
ScreenBuffer.stroke(Math.random() * 255)
ScreenBuffer.point(x,y)
}
}
}
Although I am getting a performance improvement, its nowhere near the 30 frames a second I want to be at. Is there a better way to do this?
The only way I can get reasonable performance is by filling up the screen with small squares instead with the following code:
for(var x = 0; x< SCREEN_WIDTH-10; x+=10){
for(var y = 0; y< SCREEN_HEIGHT-10; y+=10){
//ScreenBuffer.stroke(Math.random() * 255)
//ScreenBuffer.point(x,y)
ScreenBuffer.fill(Math.random() * 255);
ScreenBuffer.noStroke()
ScreenBuffer.rect(x,y,10,10)
}
}
But I would really like a pixel effect - ideally to fill the whole screen.
Believe it or not, it's actually the call to stroke() that's slowing down your sketch. You can get around this by setting the value of the pixels directly, using the set() function or accessing the pixels array directly.
More info can be found in the reference, but here's a simple example:
function setup() {
createCanvas(500, 500);
}
function draw() {
for (var i = 0; i < width; i++) {
for (var j = 0; j < height; j++) {
var c = random(255);
set(i, j, c);
}
}
updatePixels();
text(frameRate(), 20, 20);
}
Another approach you might consider is generating a few buffers that contain static images ahead of time, and then using those to draw your static. There's really no need to make the static completely dynamic, so do the work once and then just load from image files or buffers created using the createGraphics() function.
I am using the following code to place an image on a spreadsheet:
var ms = new MemoryStream();
Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
_logo.Save(ms, ImageFormat.Png);
ms.Position = 0;
locationWorksheet.Pictures.Add(0, 4, ms);
AutoFitterOptions options = new AutoFitterOptions { OnlyAuto = true };
locationWorksheet.AutoFitRows(options);
It works fine; however, I use this same code on two different reports, and the image displays at different sizes. On one it has a height of 0.85" (63%) and a width of 1.1" (53%), while on the other it has a height of 1.44" (106%) and a width of 2.07" (100%).
Why would they differ in size? And why wouldn't they be 100% of the original image size?
The other code, which seems to be exactly the same (although in this case the column at which the image appears is dynamic), is:
var ms = new MemoryStream();
Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
_logo.Save(ms, ImageFormat.Png);
ms.Position = 0;
pivotTableSheet.Pictures.Add(0, _grandTotalsColumnPivotTable - 1, ms);
AutoFitterOptions options = new AutoFitterOptions { OnlyAuto = true };
pivotTableSheet.AutoFitRows(options);
The image itself, at the location referenced, has a height of 1.35" and a width of 2.07"
The method called is:
internal static Image GetURLImage(string url)
{
WebClient wc = new WebClient();
byte[] bytes = wc.DownloadData(url);
MemoryStream ms = new MemoryStream(bytes);
return Image.FromStream(ms);
}
How can I get the image to always display at 100%, or at least at a given size?
UPDATE
I also have (at least for now) some reports in the same project that are generated using EPPlus. In these, I have the following code, which allows me to set the exact size of the image:
private void AddImage(ExcelWorksheet oSheet, int rowIndex, int colIndex)
{
Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
var excelImage = oSheet.Drawings.AddPicture("PRO*ACT Logo", _logo);
excelImage.From.Column = colIndex - 1;
excelImage.From.Row = rowIndex - 1;
excelImage.SetSize(199, 130); // 199WX130H is the actual size of the image
excelImage.From.ColumnOff = Pixel2MTU(2);
excelImage.From.RowOff = Pixel2MTU(2);
}
...which is called like so:
AddImage(deliveryPerformanceWorksheet, UNIT_ROW, LOGO_FIRST_COLUMN);
...but this won't fly in the Aspose code, because the sheet is of a different type - an Aspose.Cells.Worksheet instead of an ExcelWorksheet, and thus this code:
AddImage(locationWorksheet, 0, 4);
... won't compile in the Aspose report. I wish I could temporarily convert the Aspose.Cells.Worksheet to an ExcelWorksheet as cavalierly as this:
ExcelWorksheet ews = locationWorksheet; // naive attempt to magically morph an Aspose.Cells.Worksheet to an ExcelWorksheet
AddImage(ews, 0, 4);
...so that I could call AddImage(), but that flagrant attempt is tweeted to a halt by the compiler whistling, "Cannot implicitly convert type 'Aspose.Cells.Worksheet' to 'OfficeOpenXml.ExcelWorksheet'"
UPDATE 2
The image is the expected size; this code:
int h = _logo.Height; //130, as expected
int w = _logo.Width; //199, " "
...showed the image was the original size. Could the problem be the AutoFitterOptions setting? Does OnlyAuto allow stretching/squashing of the image, depending on the size of the cell into which it is plopped?
UPDATE 3
In EPPlus I can get the images to display at exactly the same size using this code:
private void AddImage(ExcelWorksheet oSheet, int rowIndex, int colIndex)
{
Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
var excelImage = oSheet.Drawings.AddPicture("PRO*ACT Logo", _logo);
excelImage.From.Column = colIndex - 2;
excelImage.From.Row = rowIndex - 1;
excelImage.SetSize(199, 130);
excelImage.From.ColumnOff = Pixel2MTU(2);
excelImage.From.RowOff = Pixel2MTU(2);
}
...but in Aspose I can only come close using:
var ms = new MemoryStream();
Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
_logo.Save(ms, ImageFormat.Png);
ms.Position = 0;
pivotTableSheet.Pictures.Add(0, _grandTotalsColumnPivotTable - 1, ms);
And the EPPlus code also retains the height/width ratio:
The original image is 199 pixels wide and 130 pixels high.
The EPPlus-plopped images are 1.33 X 2.05, so the ratio of 1.5:1 (close approximation) is retained.
The Aspose-plopped images, though, are 1.63 and 1.67 X 2.07, so the ratio is more like 1.25:1
So even with the AutoFitter jazz commented out of the Aspose code, the image still gets either squashed in width or stretched in height.
UPDATE 4
Based on a thread here, I tried this (afer copying the image to my bin folder):
int index = locationWorksheet.Pictures.Add(0, 4, 6, 5, "LogoFromSite.png");
Picture pic = locationWorksheet.Pictures[index];
pic.Placement = PlacementType.FreeFloating;
The first four arguments to [sheet].Pictures.Add() are Upper Left Row, Upper Left Column, Lower Right Row, and Lower Right Column.
However, this puts the image on the page in the right place, but then moves it to the left several columns (!?!)
UPDATE 5
I found another ray of hope here, and tried this code:
Aspose.Cells.Rendering.ImageOrPrintOptions opts = new Aspose.Cells.Rendering.ImageOrPrintOptions();
opts.OnePagePerSheet = true;
opts.ImageFormat = ImageFormat.Png;
opts.SetDesiredSize(199, 130);
Aspose.Cells.Rendering.SheetRender sr = new Aspose.Cells.Rendering.SheetRender(locationWorksheet, opts);
sr.ToImage(0, "LogoFromSite.png");
...but got this:
So: squashed again.
UPDATE 6
I tried some code provided by the Aspose Cells cats themselves, but they admitted there was a problem with it, and were looking into it. Just for grins, I gave it a shot to see what would transpire. This code:
byte[] bts1 = File.ReadAllBytes("LogoFromSite.png");
byte[] bts2 = File.ReadAllBytes("LogoFromSite.png");
MemoryStream ms1 = new MemoryStream();
ms1.Write(bts1, 0, bts1.Length);
ms1.Position = 0;
//This is for second picture in sheet2
MemoryStream ms2 = new MemoryStream();
ms2.Write(bts2, 0, bts2.Length);
ms2.Position = 0;
//Add picture in first worksheet
int idx = locationWorksheet.Pictures.Add(0, 4, ms1);
//Add picture in second worksheet with original size
idx = locationWorksheet.Pictures.Add(0, 10, ms2);
Picture pic = locationWorksheet.Pictures[idx];
pic.HeightScale = 100;
pic.WidthScale = 100;
...resulted in these "no image images":
UPDATE 7
I made another venture; as the height was being increased above and beyond 100%, I thought I would resize the image into another one, and use that:
var ms = new MemoryStream();
Image _logo = GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
double newHeightDbl = _logo.Height * 0.8;
int newHeightInt = (int)Math.Ceiling(newHeightDbl);
Image resizedImage = ResizeImage(_logo, newHeightInt, _logo.Width);
resizedImage.Save(ms, ImageFormat.Png);
ms.Position = 0;
locationWorksheet.Pictures.Add(0, 4, ms);
...but no! It stuffs the whole shebang into one measly column, like so:
...and gumbifies it galore vertically, thus making it look queasier than a lubber on a tempest-tossed tug.
Here is the (stolen/borrowed) code to resize the image:
// from http://stackoverflow.com/questions/1922040/resize-an-image-c-sharp
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
Please check your thread in Aspose.Cells forum which answers two of your following questions.
1 - Can we reuse same memory stream object containing picture in workbooks and worksheets?
2 - How to add picture with original size?
Note: I am working as Developer Evangelist at Aspose
Simply a matter of commenting out the fancy-pants autofitting code:
//AutoFitterOptions options = new AutoFitterOptions { OnlyAuto = true };
//pivotTableSheet.AutoFitRows(options);
Now the image is displayed uniformly at pretty much its actual size (but note the caveat below); a scosh "spilly" at times, but if they complain about that, I'll create a second image, and resize it using this:
// from http://stackoverflow.com/questions/1922040/resize-an-image-c-sharp
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
Caveat emptor: This works well enough that I am grudgingly accepting it, but the images placed on the sheet are not exactly the same size. One is 1.67" X 2.07", the other is 1.63" X 2.07" - close enough for horseshoes, hand-grenades, and images on Excel spreadsheets, I guess.
In my vaadin 7 application I have a CSSLayout that contains a Tabsheet. The Tabsheet contains a horizontalLayout. The HorizontalLayout contains a Table.
The table have a varying number of columns (between 3 and 20, changes upon request).
I want this table to occupy all available space both horizontally and vertically.
Vertically however the table should not extend beyond the the screen. So in case of having more rows than it can display the table should have a vertical scrollbar. (That is the case if I set the number of rows in table.setPageLength(), however I want to achieve this without setting explicit rownumbers, because I want the table to occupy all available space regardless of screensize, etc...)
Horizontally I also want a scrollbar if there are more columns then we have space for.
If I leave everything (csslayout, tabsheet, horizontallayout, table) default, I get the scrollbars, but I get a lot of space unused.
If I use setSizeFull() on tabsheet, horizontallayout, table then I get no unused space, however I lose the horizontal scrollbar and I can't ever reach end of the table with the vertical scrollbar.
Any help is appreciated.
EDIT -- UPDATE -- EDIT -- UPDATE --EDIT -- UPDATE --EDIT -- UPDATE
Here is a sample code. On my screen it's impossible to scroll down to the last row of the table. (and equally impossible to use the horizontal scrollbar)
#Override
protected void init(#SuppressWarnings("unused") VaadinRequest request) {
CssLayout css = new CssLayout();
HorizontalLayout upper = new HorizontalLayout();
OptionGroup first = new OptionGroup();
first.addItem("AAA");
first.addItem("BBB");
first.addItem("CCC");
first.addItem("DDD");
first.addItem("EEE");
first.addItem("Whatever");
upper.addComponent(first);
css.addComponent(upper);
HorizontalLayout hl = new HorizontalLayout();
hl.setMargin(true);
hl.setSpacing(true);
IndexedContainer c = new IndexedContainer();
for (int i = 0; i < 40; i++)
c.addContainerProperty("name" + i, String.class, "name" + i);
Table table = new Table("Test table", c);
for (int i = 0; i < 100; i++) {
Integer id = (Integer) c.addItem();
c.getItem(id).getItemProperty("name0").setValue(String.valueOf(i));
}
hl.addComponent(table);
TabSheet tab = new TabSheet();
tab.addTab(hl, "Table");
css.addComponent(tab);
hl.setSizeFull();
table.setSizeFull();
tab.setSizeFull();
css.setSizeFull();
setContent(css);
}
Maybe you don't set the size full on the css layout or maybe there are some trouble with styles.
It's better posting some code in questions like Why my code dosen't work?. However I wrote a simple test following your description and work as expected.
Edit
Try with VerticalLayout instead CssLayout
public class TestTableApp extends UI {
#Override
protected void init(VaadinRequest request) {
VerticalLayout css = new VerticalLayout();
HorizontalLayout upper = new HorizontalLayout();
OptionGroup first = new OptionGroup();
first.addItem("AAA");
first.addItem("BBB");
first.addItem("CCC");
first.addItem("DDD");
first.addItem("EEE");
first.addItem("Whatever");
upper.addComponent(first);
css.addComponent(upper);
HorizontalLayout hl = new HorizontalLayout();
hl.setMargin(true);
hl.setSpacing(true);
IndexedContainer c = new IndexedContainer();
for (int i = 0; i < 40; i++)
c.addContainerProperty("name" + i, String.class, "name" + i);
Table table = new Table("Test table", c);
for (int i = 0; i < 100; i++) {
Integer id = (Integer) c.addItem();
c.getItem(id).getItemProperty("name0").setValue(String.valueOf(i));
}
hl.addComponent(table);
TabSheet tab = new TabSheet();
tab.addTab(hl, "Table");
css.addComponent(tab);
hl.setSizeFull();
tab.setSizeFull();
table.setSizeFull();
css.setSizeFull();
// this do the trick
css.setExpandRatio(upper, 0);
css.setExpandRatio(tab, 1);
setContent(css);
}
}
I'm trying to get the amount of lines in a TextView. I've searched here for a solution, basically every thread has the same answer : contentheight/fontlineheight.
I have a TextView with 8 lines, i run this code and i get contsize : 1.944413
NSLog(#"contsize : %f", descLabel.contentSize.height/descLabel.font.lineHeight);
What am i doing wrong?
For iOS7, a version that take care that you can have differents font (and font size) in your UITextView :
- (NSUInteger)numberOfLinesInTextView:(UITextView *)textView
{
NSLayoutManager *layoutManager = [textView layoutManager];
NSUInteger index, numberOfLines;
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:[textView textContainer]];
NSRange lineRange;
for (numberOfLines = 0, index = glyphRange.location; index < glyphRange.length; numberOfLines++){
(void) [layoutManager lineFragmentRectForGlyphAtIndex:index
effectiveRange:&lineRange];
index = NSMaxRange(lineRange);
}
return numberOfLines;
}
I have a DIV container somewhere on the page with min-width and min-height set to some values.
I am loading small panels (DIVs with display:inline-block) into it using callbacks and javascript.
Right now the number of panels is fixed, so that when the user maximizes the browser window, the size of the container increases, and white space appears at the end of last line.
I want to catch the container's size changes, and load more elements, as many as will fit without clipping into the container's new space.
I saw this on amazon.com. They have panels that display 4 products, but if the browser window is maximized, same panels will display more products filling all the available space in the container.
Scroll-bars must not appear, and no clipping of elements must be done.
Is there a script I could use, or sample code?
Thank you,
Andrei
Found a very nice solution to the problem.
Here's the code: (term 'display' here is used in the same sense as at the supermarket):
function updateDisplay() {
$(".s2", this).hide();
var x = $(".s2", this);
var prevPos = -1;
var nrows = 2;
for (var i = 0; i < x.length; i++) {
$(x[i]).toggle();
var curPos = $(x[i]).position().left;
if (curPos < prevPos) {
if (--nrows == 0) {
$(x[i]).toggle();
break;
}
}
prevPos = curPos;
}
}
function updateDisplays() {
$(".dcon").each(updateDisplay);
}
$(window).resize(updateDisplays);
$(document).ready(updateDisplays);
You can see it in action on the following pages:
www.megabit-mich.ru
www.sportolimpia.ru