I've been trying for at least 2 days now to control the size of the validity icon of a pdf file, when signed.
The icon is set by the pdf reader usually.
I've tried different approaches to the problem :
Redimensioned the Signature Annotation Rectangle - which reshaped
all the contents within
Redimensioned the Signature Annotation Appearance BBox - which also
reshaped the text and icon contents.
I've also tried to reshape n2 and n0 layers, and created a new one
n5, expecting to be able to control it's size without success
In the end, I would just want to individually resize the validity icon.
Any suggestions shall be deeply appreciated.
dsblank = Annotation::AppearanceStream.new.setFilter(:FlateDecode)
dsblank.Type=Name.new("XObject")
dsblank.Resources = Resources.new
dsblank.BBox = [ 0, 0, width, height ]
dsblank.draw_stream('% DSBlank')
n2 = Annotation::AppearanceStream.new.setFilter(:FlateDecode)
n2.Resources = Resources.new
n2.BBox = [ 0, 0, width, height ]
n2.draw_stream('% DSBlank')
n5 = Annotation::AppearanceStream.new.setFilter(:FlateDecode)
n5.Resources = Resources.new
n5.BBox = [ 0, 0, width, height ]
n5.write(caption,x: padding_x, y: padding_y, size: text_size, leading: text_size )
sigannot = Annotation::Widget::Signature.new
sigannot.Rect = Rectangle[ llx: x, lly: y, urx: x+width, ury: y+height ]
sigannot.F = Annotation::Flags::PRINT #sets the print mode on
#
# Creates the stream for the signature appearance
#
streamN = Annotation::AppearanceStream.new.setFilter(:FlateDecode)
streamN.BBox = [ 0, 0,width, height]
streamN.Resources = Resources.new
streamN.Resources.add_xobject(Name.new("n0"), dsblank)
streamN.Resources.add_xobject(Name.new("n1"), dsblank)
streamN.Resources.add_xobject(Name.new("n2"), n2)
streamN.Resources.add_xobject(Name.new("n3"), dsblank)
streamN.Resources.add_xobject(Name.new("n5"), n5)
streamN.draw_stream('q 1 0 0 1 0 0 cm /n0 Do Q')
streamN.draw_stream('q 1 0 0 1 0 0 cm /n1 Do Q')
streamN.draw_stream('q 1 0 0 1 0 0 cm /n2 Do Q')
streamN.draw_stream('q 1 0 0 1 0 0 cm /n3 Do Q')
streamN.draw_stream('q 1 0 0 1 0 0 cm /n5 Do Q')
sigannot.set_normal_appearance(streamN)
page.add_annot(sigannot)
This is not an answer showing how to fix it but more a comment arguing that it is a bad idea to try it at all. It is too big for a comment field, though.
You are trying to manufacture PDFs to support an Adobe Reader feature which Adobe has started phasing out a long time ago, with Adobe Reader 9!
(page 10 of Adobe Acrobat 9 Digital Signatures, Changes and Improvements)
Thus, even if you achieve your goal for now with the current Adobe Reader, it may very easily happen that in upcoming new Adobe Reader version support for this feature will completely be stopped.
Furthermore you wont find any mentioning of this feature (changing signature appearances) in the current PDF specification ISO 32000-1, let alone the upcoming ISO 32000-2.
Also maintenance of support for layers except n0 and n2 had already been stopped in Acrobat 6.0:
(page 8 of Adobe® Acrobat® SDK Digital Signature Appearances, Edition 1.0, October 2006)
After some iterations I managed to get a scale factor of 3 for streamN and n2, as well as padding_y. I also add to increase the text_size.
With that I managed to reduce the size of the icon, and still have legible text.
n2 = Annotation::AppearanceStream.new
n2.Resources = Resources.new
n2.BBox = [ 0, 0, width*3, height*3 ]
n2.write(caption,x: padding_x, y: padding_y*3, size: text_size, leading: text_size )
sigannot = Annotation::Widget::Signature.new
sigannot.Rect = Rectangle[ llx: x, lly: y, urx: x+width, ury: y+height ]
sigannot.F = Annotation::Flags::PRINT #sets the print mode on
#
# Creates the stream for the signature appearance
#
streamN = Annotation::AppearanceStream.new.setFilter(:FlateDecode)
streamN.BBox = [ 0, 0, width*3, height*3 ]
Related
I have defined a rotation matrix and wanted the Eigen::Transform to perform rotation. For some reason, it is still set at identity although I am rotating it.
//Definig my rotation matrix
Eigen::Matrix3f roll_rotation_matrix( 3, 3 );
roll_rotation_matrix << 1, 0, 0, 0, 0, 1, 0, -1, 0;
//Print
display("PRINT ROLL ROTATION: ")
display(roll_rotation_matrix)
// Perform rotation along X
display("BEFORE: ")
display(roll_input_stamped_transform.transform.rotation())
//Rotate the rotation matrix
roll_input_stamped_transform.transform.rotate( roll_rotation_matrix );
roll_input_stamped_transform.transform.rotation = roll_rotation_matrix;
//Print
display(" AFTER: ")
display(roll_input_stamped_transform.transform.rotation());
And my output here is as below:
PRINT ROLL ROTATION:
1 0 0
0 0 1
0 -1 0
BEFORE:
1 0 0
0 1 0
0 0 1
AFTER:
1 0 0
0 1 0
0 0 1
As I am printing my roll_rotation_matrix, I can see that my matrix is not identity. But, even after applying rotate(), the rotation matrix still seems to be at identity.
Do you guys have any clue as to what might me going on here?
Figured out the issue.
I had to set the roll_input_stamped_transform.transform.setIdentity() in order for it to apply my rotation matrix.
I am coding my first game using lua and roblox studio. I have a couple of questions regarding GUI. I have coded a very rudimentary gui that displays the code of the four teams that can join the game. Here is the code for the GUI. It lives in a local script inside StarterGUI:
local UpdateGUI = game.ReplicatedStorage:WaitForChild("UpdateGUI")
local StartGui = game.ReplicatedStorage:WaitForChild("StartGui")
local UpdateAllScoresLateArrival = game.ReplicatedStorage:WaitForChild("UpdateAllScoresLateArrival")
local function updateAllLabelsLateArrival(redPoints, bluePoints, yellowPoints, greenPoints)
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.Text = redPoints
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.Text = bluePoints
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.Text = yellowPoints
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.Text = greenPoints
end
local function UpdateLabel(plr, points)
if plr.team.Name == "Really red Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.Text = points
elseif plr.team.Name == "Really blue Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.Text = points
elseif plr.team.Name == "New Yeller Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.Text = points
elseif plr.team.Name == "Lime green Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.Text = points
end
end
local localPlayer = game.Players.LocalPlayer
local function StartLabel(player)
if player.Team.Name == "Really red Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeam.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.RedTeamTag.BackgroundTransparency = 0.5
elseif player.Team.Name == "Really blue Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeam.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.BlueTeamTag.BackgroundTransparency = 0.5
elseif player.Team.Name == "New Yeller Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeam.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.YellowTeamTag.BackgroundTransparency = 0.5
elseif player.Team.Name == "Lime green Team" then
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.TextTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeam.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.TextStrokeTransparency = 0
game.Players.LocalPlayer.PlayerGui.ScreenGui.GreenTeamTag.BackgroundTransparency = 0.5
end
end
UpdateGUI.OnClientEvent:Connect(UpdateLabel)
StartGui.OnClientEvent:Connect(StartLabel)
UpdateAllScoresLateArrival.OnClientEvent:Connect(updateAllLabelsLateArrival)
There is a function that starts the label that is triggered in a server side script when a player joins the game. By ''start the label'' I mean that the labels are there with a transparency of 1 and the function makes them visible when a player joins. There is a function that updates the label everytime any player scores, and a function that is triggered also when a player joins the game late to make sure it has the scores of the players already in the game. Like I said this is my first game and I was focusing on things working. Now I would like to code it properly. My goal is that the labels are allocated dynamically. That is, when a player joins the game, the label is created in code. Particularly I would want the space between the labels to be set dynamically so that the labels are centred regardless of how many players. I tried making the labels a child of a ''frame'' but the labels changed place and were difficult to manipulate. So I would like some advice as to how to set this up in code.
My goal is that the labels are allocated dynamically. That is, when a player joins the game, the label is created in code
You can create UI elements the same way you create Instances in the Workspace.
local lblTeam = Instance.new("TextLabel")
lblTeam.TextTransparency = 0
lblTeam.TextStrokeTransparency = 0
lblTeam.Name = teamName
lblTeam.Parent = game.Players.LocalPlayer.PlayerGui.ScreenGui
I would want the space between the labels to be set dynamically so that the labels are centered regardless of how many players there are.
The way UI elements are laid out in Roblox are with UDim2 values for Size and Position.
A UDim2's constructor looks like this : UDim2.new(xScale, xOffset, yScale, yOffset). Scale refers to with percentage of the parent container should this dimension span, and Offset are the number of pixels extra to add. So some examples :
local lbl = Instance.new("TextLabel")
lbl.Size = UDim2.new(0, 50, 0, 10) -- 50 pixel wide and 10 pixel tall
lbl.Size = UDim2.new(1, 0, 1, 0) -- 100% wide by 100% tall
lbl.Size = UDim2.new(1, -10, 1, -10) -- 100% wide and tall, minus 10 pixels on both bottom and right
-- assuming no changes to AnchorPoint...
lbl.Position = UDim2.new(0, 0, 0, 0) -- upper left corner is upper left corner of parent
lbl.Position = UDim2.new(0.5, 0, 0.5, 0) -- upper left corner is dead center
lbl.Position = UDim2.new(1, 0, 0, 0) -- upper left corner is offscreen on the right
Now, if you want your stuff to be dynamically placed, you could manually place these objects using Positions, but I would recommend using a UIListLayout object and using the LayoutIndex property to automatically place objects for you. It will automatically handle the Position property for you.
local function createTeamUI(name, parent, teamName, index)
-- make a small frame to hold each team UI
-- looks like : [[ Team Tag Label ][ Team Points Label ]]
local teamFrm = Instance.new("Frame")
teamFrm.BackgroundTransparency = 1
teamFrm.Size = UDim2.new(1, 0, 0, 30) -- relative to parent : 100% wide, 30px tall
teamFrm.Name = name
teamFrm.LayoutIndex = index
local lblTeamTag = Instance.new("TextLabel", teamFrm)
lblTeamTag.TextTransparency = 0
lblTeamTag.TextStrokeTransparency = 0
lblTeamTag.Name = "TeamTag"
lblTeamTag.Text = teamName
lblTeamTag.Size = UDim2.new(0.5, 0, 1, 0) -- relative to teamFrm : 50% wide, 100% tall
lblTeam.Position = UDim2.new(0, 0, 0, 0)
local lblPoints = Instance.new("TextLabel", teamFrm)
lblPoints.TextStrokeTransparency = 0
lblPoints.BackgroundTransparency = 0.5
lblPoints.Name = "Points"
lblPoints.Text = "0"
lblPoints.Size = UDim2.new(0.5, 0, 1, 0) -- relative to teamFrm
lblPoints.Position = UDim2.new(0.5, 0, 0, 0)
-- optimization : set the parent last
teamFrm.Parent = parent
return teamFrm
end
local function createAllTeamLabels()
-- creates a list of UI
local frm = Instance.new("Frame")
frm.Name = "Teams"
frm.Size = UDim2.new(0.3, 0, 1, 0)
frm.BackgroundTransparency = 1.0
local layout = Instance.new("UIListLayout")
layout.LayoutOrder = Enum.SortOrder.LayoutIndex
layout.FillDirection = Enum.FillDirection.Vertical
layout.Padding = UDim.new(0, 10) -- 10 pixels between each element in the list
local frmTeamA = createTeamLabel("RedTeam", frm, "Really Red Team", 0)
local frmTeamB = createTeamLabel("BlueTeam", frm, "Blue Team", 1)
local frmTeamC = createTeamLabel("GreenTeam", frm, "Green Team", 2)
frm.Parent = game.Players.LocalPlayer.PlayerGui.ScreenGui
end
local function updatePoints(teamName, points)
game.Players.LocalPlayer.PlayerGui.ScreenGui.Teams[teamName].Points.Text = tostring(points)
end
I have noticed that when a player dies, the GUI disappears on respawn
There is a property on ScreenGuis called ResetOnSpawn that you can change to false. That will keep the UI around even after a player resets.
Since you are making your UI dynamically in code, you should be careful that you aren't accidentally creating the UI multiple times. Here's where the differences between StarterPlayer > StarterPlayerScripts and StarterPlayer > StarterCharacterScripts become important. A LocalScript inside StarterPlayerScripts will run when the player first joins, and a LocalScript inside StarterCharacterScripts will run every time the player's character reloads. So be careful where you fire the code to create the UI.
Hope this helps!
I want a fullscreen GUI with a gutter net of 96x96 pixels and a small gutter border (maybe a pixel). The GUI should be a transparent overlay (just the gutter net should be displayed).
Why? I often work with sprite-sheet images (create, resize or rearrange them). I do not have software which supports gutter lines as help view. It would be great to have for a quick accurate adjustment.
I use a fullscreen GUI as $WS_POPUP (borderless) window. The gutter is a label with specific background color. I have to manually create these so I hope you have a better idea.
My code so far:
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
$iGuiW = #DesktopWidth
$iGuiH = #DesktopHeight
$iGuiGutterSize = 96
$hColor = 0x00FF00
$hGui = GUICreate("", #DesktopWidth, #DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
; From left to right.
GUICtrlCreateLabel("", 0, 0, $iGuiW, 1)
GUICtrlSetBkColor(-1, $hColor)
GUICtrlCreateLabel("", 0, $iGuiGutterSize, $iGuiW, 1)
GUICtrlSetBkColor(-1, $hColor)
GUICtrlCreateLabel("", 0, $iGuiGutterSize * 2, $iGuiW, 1)
GUICtrlSetBkColor(-1, $hColor)
GUICtrlCreateLabel("", 0, $iGuiGutterSize * 3, $iGuiW, 1)
GUICtrlSetBkColor(-1, $hColor)
; From top to bottom.
GUICtrlCreateLabel("", 0, 0, 1, $iGuiH)
GUICtrlSetBkColor(-1, $hColor)
GUICtrlCreateLabel("", $iGuiGutterSize, 0, 1, $iGuiH)
GUICtrlSetBkColor(-1, $hColor)
GUICtrlCreateLabel("", $iGuiGutterSize * 2, 0, 1, $iGuiH)
GUICtrlSetBkColor(-1, $hColor)
GUICtrlCreateLabel("", $iGuiGutterSize * 3, 0, 1, $iGuiH)
GUICtrlSetBkColor(-1, $hColor)
GUISetState( #SW_SHOW, $hGui )
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
GUIDelete($hGui)
Exit
EndSwitch
WEnd
How to get the GUI to be transparent except the gutter lines?
How can I do it without manually setting label by label for each line (row and column)?
Yes it's like a grid design but just the borders as lines.
Notice:
It's a bit unclear that my suggestion fits your imaginations, but I guess you mean something like a grid design. As you mentioned the GUI is like a overlay (transparent) and just the grid lines are visible.
The solution is in the _createGridStructure() function which uses some WinAPI functions to provide such a grid (rectangle design). I extracted your GUIDelete($hGui) and Exit in a separat function _disposeAndExit(). I also extracted the GUI creation part in a function to be a bit more flexible.
Approach:
#include-once
#include <GuiConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Global $iGuiWidth = #DesktopWidth
Global $iGuiHeight = #DesktopHeight
Global $iGridSize = 96 ; change the size if you want
Global $vGridColor = 0x00FF00 ; change the grid line color if you want
Global $hMainGui
Func _createGui()
$hMainGui = GUICreate( '', $iGuiWidth, $iGuiHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST )
GUISetBkColor( $vGridColor )
GUISetState( #SW_SHOW, $hMainGui )
EndFunc
Func _createGridStructure()
Local $iGridLinesX = Floor( $iGuiWidth / $iGridSize )
Local $iGridLinesY = Floor( $iGuiHeight / $iGridSize )
Local $hMainRegion = _WinAPI_CreateRectRgn( 0, 0, 0, 0 )
For $i = 0 To $iGridLinesX Step 1
$hRegion = _WinAPI_CreateRectRgn( $i * $iGridSize, 0, ( $i * $iGridSize ) + 1, $iGuiHeight )
_WinAPI_CombineRgn( $hMainRegion, $hRegion, $hMainRegion, 2 )
_WinAPI_DeleteObject( $hRegion )
Next
For $i = 0 To $iGridLinesY Step 1
$hRegion = _WinAPI_CreateRectRgn( 0, $i * $iGridSize, $iGuiWidth, ( $i * $iGridSize ) + 1 )
_WinAPI_CombineRgn( $hMainRegion, $hRegion, $hMainRegion, 2 )
_WinAPI_DeleteObject( $hRegion )
Next
_WinAPI_SetWindowRgn( $hMainGui, $hMainRegion )
EndFunc
Func _disposeAndExit()
GUIDelete( $hMainGui )
Exit
EndFunc
_createGui()
_createGridStructure()
While 1
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
_disposeAndExit()
EndSwitch
WEnd
Now you don't have to manually adjust the grid lines if you switch the monitor resolution.
The matlab code below splits up an image into a number of smaller images. It then counts the number of black pixels in the image and displays it as a percentage of the total number of pixels in the picture. example of image
My question is - instead of counting the black pixels and displaying the percentage, how can I count the white pixels? (essentially the opposite!)
Thanks
% Divide an image up into blocks (non-overlapping tiles).
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
fontSize = 20;
% Read the image from disk.
rgbImage = imread('edge-diff.jpg');
% Display image full screen.
imshow(rgbImage);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
drawnow;
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage)
%==========================================================================
% The first way to divide an image up into blocks is by using mat2cell().
blockSizeR = 400; % Rows in block.
blockSizeC = 400; % Columns in block.
% Figure out the size of each block in rows.
% Most will be blockSizeR but there may be a remainder amount of less than that.
wholeBlockRows = floor(rows / blockSizeR);
blockVectorR = [blockSizeR * ones(1, wholeBlockRows), rem(rows, blockSizeR)];
% Figure out the size of each block in columns.
wholeBlockCols = floor(columns / blockSizeC);
blockVectorC = [blockSizeC * ones(1, wholeBlockCols), rem(columns, blockSizeC)];
% Create the cell array, ca.
% Each cell (except for the remainder cells at the end of the image)
% in the array contains a blockSizeR by blockSizeC by 3 color array.
% This line is where the image is actually divided up into blocks.
if numberOfColorBands > 1
% It's a color image.
ca = mat2cell(rgbImage, blockVectorR, blockVectorC, numberOfColorBands);
else
ca = mat2cell(rgbImage, blockVectorR, blockVectorC);
end
percentBlack = cellfun(#(x)sum(sum(all(x == 0, 3))) / (numel(x) / size(x,3)), ca);
% Now display all the blocks.
plotIndex = 1;
numPlotsR = size(ca, 1);
numPlotsC = size(ca, 2);
for r = 1 : numPlotsR
for c = 1 : numPlotsC
fprintf('plotindex = %d, c=%d, r=%d\n', plotIndex, c, r);
% Specify the location for display of the image.
subplot(numPlotsR, numPlotsC, plotIndex);
ax2 = subplot(numPlotsR, numPlotsC, plotIndex);
% Extract the numerical array out of the cell
% just for tutorial purposes.
rgbBlock = ca{r,c};
imshow(rgbBlock); % Could call imshow(ca{r,c}) if you wanted to.
[rowsB columnsB numberOfColorBandsB] = size(rgbBlock);
set(ax2, 'box', 'on', 'Visible', 'on', 'xtick', [], 'ytick', []);
% Make the caption the block number.
averageBlack = percentBlack(r,c);
disp(numPlotsR);
disp(averageBlack);
caption = sprintf('Frame #%d of %d\n Percentage information content %0.2f', ...
plotIndex, numPlotsR*numPlotsC, averageBlack*100);
title(caption);
drawnow;
% Increment the subplot to the next location.
plotIndex = plotIndex + 1;
end
end
This line:
percentBlack = cellfun(#(x)sum(sum(all(x == 0, 3))) / (numel(x) / size(x,3)), ca);
specifically the part that says all(x == 0, 3) means "all color channels have value 0". You want to change it to "all color channels have value 1 (or 255 depends on your image)"
So basically, change that 0 to 1 or 255, deependinf if your image is unit8 or double
I have the following code:
red = [1 255 0; 0 0 0; 0 0 0];
green = [0 0 0; 0 0 0; 0 0 0];
blue = [0 0 0; 0 0 0; 0 0 0];
figure,imshow(cat(3,red,green,blue))
According to my "intuitive" understanding the color of the first pixel of the image should have the following rgb components: (1,0,0), while the second pixel should have the following components: (255,0,0) (when I say the "first" and "second" I mean the text order: from left to right, from top to bottom).
In other words the first pixel should be almost absolutely black while the second one should be red. However, the both pixels look perfectly red. What am I missing here?
I'm no expert, but I think it's because you're passing doubles to imshow. You could try
imshow(uint8(cat(3, red, green, blue)))